PermGen与电梯和docker的问题
我正在开发标准的升降平台(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。 我认为我认为永久的一代记忆是用于类和string的东西是正确的? 我记得有点与.NET内存模型混淆了…
为什么会发生这种情况? 默认值是疯狂的低? 它是否与所有的Scala必须为函数对象和类似的FP事物创build的辅助对象? 每次我用新编写的代码(每隔几分钟)就重新启动Jetty,我想它会重新加载类。但是即使如此,它不能成为那么多吗? JVM不能够处理大量的类吗?
干杯
乔
从这个职位 :
出现这种例外的原因很简单:
permgenspace
是Java VM中存储的类属性,比如方法,字段,注释和静态variables等,但是这个空间具有不被垃圾收集器清理的特殊性。 所以如果你的web应用程序使用或创build了很多类(我正在考虑几代dynamic类),那么你很可能遇到了这个问题。 这里有一些解决scheme,帮助我摆脱了这个例外:
-
-XX:+CMSClassUnloadingEnabled
:此设置启用垃圾邮件收集 -
-XX:+CMSPermGenSweepingEnabled
:允许垃圾收集器从内存中删除偶数类 -
-XX:PermSize=64M -XX:MaxPermSize=128M
:增加分配给Permgenspace的内存量
可能是这可能有所帮助。
编辑2012年7月(近3年后):
OndraŽižka评论(我已经更新了上面的答案):
JVM 1.6.0_27说:请使用:
-
CMSClassUnloadingEnabled
(使用CMS GC时是否启用类卸载) - 以代替
CMSPermGenSweepingEnabled
查看完整的热点JVM选项 – mroe 的完整参考 。
如果在运行mvn jetty:run
时看到这个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
。
你也可以把这些永久的放在你的环境中。
-
对于Linux,将
export
行附加到~/.bashrc
-
对于Windows,请按
Win-key + PrintScreen
,然后进入Advanced > Environment
。 另请参阅http://support.microsoft.com/kb/310519 。
这是因为你所build议的重新加载类。 如果你正在使用大量的库,那么类的总和将会在每次重启时迅速增长。 尝试使用VisualVM监控您的jetty实例,以获得重新加载时内存消耗的概述。
邮件列表( http://groups.google.com/group/liftweb/ )是Lift的官方支持论坛,您可以从中获得更好的答案。 我不知道你的开发设置的详细信息(你不会详细说明),但是我假设你在Jetty中重新加载了你的战争而没有重新启动它。 Lift不会执行dynamic类生成(如上面VonC所build议的那样),但是Scala将每个闭包编译为一个单独的类。 如果您在几天的时间内向您的代码添加和移除闭包,可能会有太多的类正在被加载,并且从未卸载并占用烫发空间。 我build议你启用VonC上面提到的选项JVM选项,看看他们是否有帮助。
永久代是JVM放置的东西,可能不会像收集自定义类加载器(垃圾)那样收集。
根据您的部署,烫发设置可能很低。 某些应用程序和/或容器组合确实包含一些内存泄漏,所以当某个应用程序被取消部署时,有时类似于类加载器的东西不会被收集,导致填充Perm空间,从而产生错误。
不幸的是,目前在这种情况下最好的select是通过下面的jvm标志来最大化perm空间(例如192m perm大小):
-XX:MaxPermSize=192M (or 256M)
另一种select是确保容器或框架不泄漏内存。