第一次应用启动正确。然后我删除webapp / * .war文件并粘贴* .war的新版本。 Jetty开始部署新战争,但发生错误java.lang.OutOfMemoryError: PermGen space
。如何配置Jetty以修复错误/进行正确的重新部署?
这solution对我没有帮助 Jetty版本:jetty-7.4.3.v20110701
答案 0 :(得分:11)
可能无法解决问题。每个JVM都有一个PermGen内存区域,用于类加载和静态数据。每当你的应用程序被取消部署时,它的类加载器应该被丢弃,并且所有类也都被它加载。如果由于对类加载器的其他引用仍然存在而失败,那么收集类加载器和应用程序类的垃圾也将失败。
A blog entry和its follow up解释了问题的可能来源。只要应用程序容器的代码使用包含对其中一个类的引用的类,就会阻止类的垃圾回收。上述博客条目中的示例是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提供的任何类中,因此无法在您的应用程序中修复。您无法通过仅更改自己的代码来阻止此问题!
您的选择基本上是:
答案 1 :(得分:7)
如果发生PermGen内存不足,则需要重新启动jvm,在你的情况下重新启动jetty。您可以使用链接解决方案中的JVM选项增加PermGen空间,以便稍后进行(稍后我的意思是:在重新部署之后)。但它会偶尔发生,你可以做到无所不能,以避免这种情况。您链接的答案很好地解释了PermGenSpace是什么以及它溢出的原因。
使用:
-XX:PermSize=64M -XX:MaxPermSize=128M
或者,如果那还不够
-XX:PermSize=256M -XX:MaxPermSize=512M
另外,如果使用此命令,请务必增加vm可用的空间量。
使用
-Xms128M -Xmx256M
答案 2 :(得分:1)
对于Jetty 7.6.6或更高版本,这可能有助于http://www.eclipse.org/jetty/documentation/current/preventing-memory-leaks.html。
我们使用了AppContextLeakPreventer
,它有助于因permgen空间而导致的OOM错误
答案 3 :(得分:0)
我对HotSpot也有同样的问题,但是对于没有永久代的JRockit,问题已经消失了。它现在是免费的,所以您可能想尝试一下:https://blogs.oracle.com/henrik/entry/jrockit_is_now_free_and
答案 4 :(得分:0)
看起来非常像Permanent Generation leak。每当您的应用程序在取消部署后让某些类挂起时,您就会遇到此问题。您可以尝试使用最新版本的Plumbr,也可以找到剩余的类。
答案 5 :(得分:0)
对于未来的读者(相对于提出这个问题时):
在 JDK 8 中,Perm Gen Space消失了(不再存在)。相反,现在Metaspace取自机器的原生空间。
如果您遇到Perm Gen Overflow问题,那么您可能需要查看this explanation和this comments on the removal process。