5

第一次应用程序正确启动。然后我删除 webapp/*.war 文件并粘贴新版本的 *.war。Jetty 开始部署新战争但java.lang.OutOfMemoryError: PermGen space发生错误。如何配置 Jetty 以修复错误/进行正确的重新部署?

这个解决方案对我没有帮助。
码头版本:jetty-7.4.3.v20110701

4

6 回答 6

11

可能没有办法解决问题。每个 JVM 都有一个用于类加载和静态数据的 PermGen 内存区域。每当您的应用程序被取消部署时,它的类加载器都应该被丢弃,并且所有由它加载的类也应该被丢弃。当由于对类加载器的其他引用仍然存在而失败时,垃圾收集类加载器和您的应用程序类也将失败。

一篇博客文章及其后续文章解释了问题的可能根源。每当应用程序容器的代码使用包含对您的某个类的引用的类时,就会阻止对您的类进行垃圾收集。上述博客条目中的示例是java.util.logging.Level构造函数:

protected Level(String name, int value) {
    this.name = name;
    this.value = value;
    synchronized (Level.class) {
        known.add(this);
    }
}

请注意,它known是 的静态成员java.util.logging.Level。构造函数存储对所有已创建实例的引用。因此,一旦Level从您的应用程序代码中加载或实例化了类,垃圾收集就无法删除您的类。

要解决这个问题,您可以避免使用您自己的代码使用的所有类,或者确保没有使用您的代码对您的类进行引用。这两个问题都可能发生在随 Java 提供的任何类中,因此在您的应用程序中修复是不可行的。您无法通过仅更改自己的代码来防止问题!

您的选择基本上是:

  • 增加内存限制并减少错误发生的频率
  • 按照链接的博客文章中的详细说明分析您的代码,并避免使用存储对您的对象的引用的类
于 2011-09-17T21:32:52.593 回答
7

如果 PermGen 发生内存不足,您需要重新启动 jvm,在您的情况下重新启动码头。您可以使用链接解决方案中的 JVM 选项增加 PermGen 空间,以便稍后发生(我的意思是稍后:在更多重新部署之后)。但它每隔一段时间就会发生一次,你几乎可以做任何事情来避免这种情况。您链接的答案很好地解释了 PermGenSpace 是什么以及它为什么会溢出。

利用:

-XX:PermSize=64M -XX:MaxPermSize=128M

或者,如果这还不够

-XX:PermSize=256M -XX:MaxPermSize=512M

此外,如果您使用此命令,请务必增加一般虚拟机的可用空间量。

利用

-Xms128M -Xmx256M
于 2011-09-15T12:17:23.230 回答
1

对于 Jetty 7.6.6 或更高版本,这可能对http://www.eclipse.org/jetty/documentation/current/preventing-memory-leaks.html有所帮助。

我们使用了AppContextLeakPreventer它,它有助于解决由于 permgen 空间引起的 OOM 错误

于 2014-10-17T14:09:58.837 回答
0

我对 HotSpot 也有同样的问题,但是对于没有永久代的 JRockit,问题就消失了。它现在是免费的,所以您可能想尝试一下:https ://blogs.oracle.com/henrik/entry/jrockit_is_now_free_and

于 2012-02-17T14:42:56.567 回答
0

看起来很像永久代泄漏。每当您的应用程序在取消部署后留下一些类闲置时,您就会遇到这个问题。您可以尝试最新版本的Plumbr,它可能会找到剩余的类。

于 2012-07-17T09:04:36.887 回答
0

对于未来的读者(相对于何时提出此问题):

JDK 8中,Perm Gen Space 消失了(不再存在)。取而代之的是现在的元空间,它取自机器的本机空间。

如果你有 Perm Gen Overflow 的问题,那么你可能想看看这个解释这个关于删除过程的评论

于 2014-03-13T08:50:04.307 回答