PermGen与Lift和Jetty有关的问题

时间:2009-09-20 18:21:01

标签: memory scala jvm lift permanent-generation

我正在开发标准的Lift平台(maven和jetty)。我反复(每隔几天一次)得到这个:

Exception in thread "7048009@qtp-3179125-12" java.lang.OutOfMemoryError: PermGen space
2009-09-15 19:41:38.629::WARN:  handle failed
java.lang.OutOfMemoryError: PermGen space

这是我的开发环境。这不是问题,因为我可以继续重启服务器。在部署中我没有遇到这些问题所以这不是一个真正的问题。我只是好奇。

我对JVM知之甚少。我认为我认为永久代内存适用于类和内部字符串之类的东西是正确的吗?我记得有点混淆了.NET内存模型...

出现这种情况的原因是什么?默认值是否疯狂低?是否与Scala必须为Function对象和类似的FP事物创建的所有辅助对象有关?每当我用新编写的代码(每隔几分钟)重新启动Jetty时,我想它会重新加载类等等。但即便如此,它也不能用很多可以吗? JVM是否应该能够处理大量的类?

干杯

5 个答案:

答案 0 :(得分:44)

来自this post

  

出现这种例外的原因很简单:
   permgenspace 是Java VM中存储类属性(如方法,字段,注释和静态变量等)的位置,但此空间具有不清除的特性由垃圾收集器。   因此,如果您的webapp使用或创建了很多类(我正在考虑动态的几代课程),那么您很可能遇到了这个问题。   以下是一些帮助我摆脱这种异常的解决方案:

  • -XX:+CMSClassUnloadingEnabled:此设置启用permgenspace中的垃圾收集
  • -XX:+CMSPermGenSweepingEnabled:允许垃圾收集器从内存中删除偶数类
  • -XX:PermSize=64M -XX:MaxPermSize=128M:提高分配给permgenspace的内存量

可能会有所帮助。

2012年7月编辑(差不多3年后):

Ondra Žižka评论(我已经更新了上面的答案):

  

JVM 1.6.0_27说:请使用:

  • CMSClassUnloadingEnabled(使用CMS GC时是否启用了类卸载)
  • 代替CMSPermGenSweepingEnabled将来

请参阅mroe的完整Hotspot JVM Options - The complete reference

答案 1 :(得分:12)

如果您在运行mvn jetty:run时看到此信息, 设置MAVEN_OPTS

对于Linux:

export MAVEN_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run

对于Windows:

set "MAVEN_OPTS=-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run

现在应该没问题。如果没有,请增加-XX:MaxPermSize

您也可以永久地将这些内容放到您的环境中。

答案 2 :(得分:3)

这是因为您按照建议重新加载了类。如果您使用大量库等,则每次重新启动时类的总和将快速增长。尝试使用VisualVM监视jetty实例,以便在重新加载时获得内存消耗的概述。

答案 3 :(得分:2)

邮件列表(http://groups.google.com/group/liftweb/)是Lift的官方支持论坛,您可以在这里获得更好的答案。我不知道您的开发设置的详细信息(您没有详细介绍),但我认为您正在重新加载Jetty中的战争而不实际重新启动它。 Lift不执行动态类生成(如上面的VonC所示),但Scala将每个闭包编译为单独的类。如果您在几天内添加和删除代码中的闭包,则可能会加载太多类并且从不卸载并占用perm空间。我建议您启用上面VonC提到的选项JVM选项,看看它们是否有帮助。

答案 4 :(得分:1)

永久代是JVM放置的东西,可能不像自定义类加载器一样(垃圾)收集。

根据您的部署情况,perm gen设置可能较低。某些应用程序和/或容器组合确实包含一些内存泄漏,因此当应用程序取消部署时,有时会收集类加载器等某些内容,从而导致填充Perm Space,从而产生您所遇到的错误。

不幸的是,目前在这种情况下最好的选择是使用以下jvm标志来最大化烫发空间(例如,对于perm大小为192m):

-XX:MaxPermSize=192M (or 256M)

另一个选择是确保容器或框架不会泄漏内存。