Lift 和 Jetty 的 PermGen 问题
我正在标准 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 不应该能够处理大量的类吗?
干杯
乔
I'm developing on the standard Lift platform (maven and jetty). I'm repeatedly (once every couple of days) getting this:
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
This is in my dev environment. It's not a problem because I can keep restarting the server. In deployment I'm not having these problems so it's not a real issue. I'm just curious.
I don't know too much about the JVM. I think I'm correct in thinking that permanent generation memory is for things like classes and interned strings? What I remember is a bit mixed up with the .NET memory model...
Any reason why this is happening? Are the defaults just crazily low? Is it to do with all the auxiliary objects that Scala has to create for Function objects and similar FP things? Every time I restart Jetty with newly written code (every few minutes) I imagine it re-loads classes etc. But even so, it cant' be that many can it? And shouldn't the JVM be able to deal with a large number of classes?
Cheers
Joe
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
来自这篇文章 :
-XX:+CMSClassUnloadingEnabled
:此设置启用永久空间中的垃圾收集-XX:+CMSPermGenSweepingEnabled
:允许垃圾收集收集器从内存中删除甚至类-XX:PermSize=64M -XX:MaxPermSize=128M
:增加分配给 permgenspace 的内存量这可能会有所帮助。
2012 年 7 月编辑(差不多 3 年后):
Ondra Žižka 评论(我已经更新了上面的答案):
CMSClassUnloadingEnabled
(使用 CMS GC 时是否启用类卸载)CMSPermGenSweepingEnabled
查看完整内容 热点 JVM 选项 - mroe 的完整参考。
From this post:
-XX:+CMSClassUnloadingEnabled
: this setting enables garbage collection in the permgenspace-XX:+CMSPermGenSweepingEnabled
: allows the garbage collector to remove even classes from the memory-XX:PermSize=64M -XX:MaxPermSize=128M
: raises the amount of memory allocated to the permgenspaceMay be this could help.
Edit July 2012 (almost 3 years later):
Ondra Žižka comments (and I have updated the answer above):
CMSClassUnloadingEnabled
(Whether class unloading enabled when using CMS GC)CMSPermGenSweepingEnabled
in the futureSee the full Hotspot JVM Options - The complete reference for mroe.
如果您在运行
mvn jetty:run
时看到此内容,设置
MAVEN_OPTS
。对于 Linux:
对于 Windows:
现在应该没问题了。如果不是,请增加
-XX:MaxPermSize
。您还可以将它们永久地放入您的环境中。
对于 Linux,将
export
行附加到~/.bashrc
对于Windows,按
Win-key + PrintScreen
,然后转到高级> >~/.bashrc
环境。请参阅http://support.microsoft.com/kb/310519。
If you see this when running
mvn jetty:run
,set the
MAVEN_OPTS
.For Linux:
For Windows:
Should be fine now. If not, increase
-XX:MaxPermSize
.You can also put these permanently to your environment.
For Linux, append the
export
line to~/.bashrc
For Windows, press
Win-key + PrintScreen
, and goAdvanced > Environment
.See also http://support.microsoft.com/kb/310519.
这是因为按照您的建议重新加载了类。如果您使用大量库等,每次重新启动时类的总数将快速增长。尝试使用 VisualVM 监控您的 jetty 实例,以了解重新加载时的内存消耗情况。
This is because of the reloading of classes as you suggested. If you are using lots of libraries etc. the sum of classes will rapidly grow for each restart. Try monitoring your jetty instance with VisualVM to get an overview of memory consumption when reloading.
邮件列表 (http://groups.google.com/group/liftweb/)是 Lift 的官方支持论坛,您可以在这里获得更好的答案。我不知道你的开发设置的细节(你没有详细说明),但我假设你正在 Jetty 中重新加载你的战争,而没有实际重新启动它。 Lift 不执行动态类生成(如上面 VonC 所建议的),但 Scala 将每个闭包编译为单独的类。如果您在几天的时间内向代码添加和删除闭包,则可能会加载太多类但从未卸载并占用永久空间。我建议您启用上面 VonC 提到的选项 JVM 选项,看看它们是否有帮助。
The mailing list (http://groups.google.com/group/liftweb/) is the official support forum for Lift, and where you'll be able to get a better answer. I don't know the particulars of your dev setup (you don't go into much detail), but I assume you're reloading your war in Jetty without actually restarting it. Lift doesn't perform dynamic class generation (as suggested by VonC above), but Scala compiles each closure as a separate class. If you're adding and removing closures to your code over the course of several days, it's possible that too many classes are being loaded and never unloaded and taking up perm space. I'd suggest you enable the options JVM options mentioned by VonC above and see if they help.
永久代是 JVM 放置可能不会像自定义类加载器那样被(垃圾)收集的东西的地方。
根据您所部署的内容,永久代设置可能会较低。某些应用程序和/或容器组合确实包含一些内存泄漏,因此当应用程序取消部署时,有时不会收集类加载器等一些内容,导致填充 Perm 空间,从而生成您遇到的错误。
不幸的是,目前这种情况下最好的选择是使用以下 jvm 标志来最大化 perm 空间(例如 192m perm 大小):
另一个选项是确保容器或框架不会泄漏内存。
The permanent generation is where the JVM puts stuff that will probably not be (garbage) collected like custom classloaders.
Depending on what you are deploying, the perm gen setting can be low. Some applications and/or containers combination do contain some memory leaks, so when an app gets undeployed sometimes some stuff like class loaders are not collected, resulting in filling the Perm Space thus generating the error you are having.
Unfortunately, currently the best option in this case is to max up the perm space with the following jvm flag (example for 192m perm size):
The other option is to make sure that either the container or the framework do not leak memory.