Memory 电梯和码头的永久性问题

Memory 电梯和码头的永久性问题,memory,scala,jvm,lift,permanent-generation,Memory,Scala,Jvm,Lift,Permanent Generation,我正在开发标准升降平台(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 这是在我的开发环境中。这不是问题,因为我可以继续重新启动服务器

我正在开发标准升降平台(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为函数对象和类似的FP对象创建的所有辅助对象有关吗?每次我用新编写的代码(每隔几分钟)重新启动Jetty时,我都会想象它会重新加载类等。但即便如此,也不可能有那么多人可以吗?JVM难道不能处理大量的类吗

干杯


Joe

永久生成是JVM放置可能不会像定制类加载器那样(垃圾)收集的内容的地方

根据部署的内容,perm gen设置可能较低。某些应用程序和/或容器组合确实包含一些内存泄漏,因此,当一个应用程序被取消部署时,某些内容(如类加载器)有时不会被收集,从而导致填充Perm空间,从而产生错误

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

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

来自:

发生此异常的原因很简单:
permgenspace
是Java VM中存储类属性(如方法、字段、注释以及静态变量等)的地方,但该空间具有不被垃圾收集器清理的特殊性。 因此,如果你的webapp使用或创建了很多类(我认为是类的动态生成),你很可能会遇到这个问题。 以下是一些帮助我摆脱此异常的解决方案:

  • -XX:+CMSClassUnloadingEnabled
    :此设置启用永久空间中的垃圾收集
  • -XX:+cmd
    :允许垃圾收集器从内存中删除偶数类
  • -XX:PermSize=64M-XX:MaxPermSize=128M
    :增加分配给永久空间的内存量
也许这会有帮助

2012年7月编辑(近3年后):

评论(我已更新了上述答案):

JVM 1.6.027说:请使用:

  • CMSClassUnloadingEnabled
    (使用CMS GC时是否启用类卸载)
  • 取代
    CMS,在将来启用

查看mroe的完整信息。

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

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

如果在运行mvn jetty:run时看到此情况, 设置
MAVEN\u选项

对于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

您还可以将它们永久地放到您的环境中

  • 对于Linux,在
    ~/.bashrc

  • 对于Windows,按Win键+PrintScreen,然后转到环境。 另见


谢谢。我认为要么调整GC的行为,要么调整PermGen的大小,都可以解决这个问题。我真的在寻找(/if)Lift将气球化PermGen对象的一个具体原因。可能是因为Lift执行了一些动态类生成。JVM 1.6.027说:请在将来使用
cmsclasssUnloadingEnabled
代替
CMSPermGenSweepingEnabled
。@OndraŽIžka说得好。我已经更新了答案,并添加了一个指向所有JVM选项的链接,以供将来参考。@gyozokudor您的意思是,为了取消编辑,您不能恢复到该答案的以前版本吗?如文章中所述:“JVM的分代垃圾收集器针对这样的情况进行了优化,因为隐式创建的对象是短期的,所以它们将非常适合GC。“。但如果这些物体不是短命的,那就另当别论了。谢谢。我通常会向谷歌集团发帖,但我想我会试试StackOverflow。将尝试增加数字。MaxPermSize和192m之间需要有一个“=”。
set "MAVEN_OPTS=-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run