scala Lift 和 Jetty 的永久代问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1451648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 01:39:19  来源:igfitidea点击:

PermGen problems with Lift and Jetty

memoryscalajvmliftpermanent-generation

提问by Joe

I'm developing on the standard Lift platform (maven and jetty). I'm repeatedly (once every couple of days) getting this:

我正在标准 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

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...

我不太了解JVM。我认为我认为永久代内存用于类和实习字符串之类的东西是正确的?我记得有点与 .NET 内存模型混淆......

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?

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

Cheers

干杯

Joe

回答by VonC

From this post:

这篇文章

This exception occurred for one simple reason :
the permgenspaceis where class properties, such as methods, fields, annotations, and also static variables, etc. are stored in the Java VM, but this space has the particularity to not being cleaned by the garbage collector. So if your webapp uses or creates a lot of classes (I'm thinking dynamic generations of classes), chances are you met this problem. Here are some solutions that helped me get rid of this exception :

发生此异常的原因很简单:
permgenspace就是类的属性,如方法,字段,注释,也静态变量等存储在Java虚拟机,但这个空间具有特殊性,以不被垃圾收集器清洗. 因此,如果您的 web 应用程序使用或创建了很多类(我正在考虑动态生成类),那么您很可能会遇到这个问题。以下是一些帮助我摆脱此异常的解决方案:

  • -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 permgenspace
  • -XX:+CMSClassUnloadingEnabled:此设置在永久空间中启用垃圾收集
  • -XX:+CMSPermGenSweepingEnabled: 允许垃圾收集器从内存中删除偶数类
  • -XX:PermSize=64M -XX:MaxPermSize=128M: 增加分配给永久空间的内存量

May be this could help.

可能这会有所帮助。

Edit July 2012 (almost 3 years later):

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

Ondra ?i?kacomments (and I have updated the answer above):

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

JVM 1.6.0_27 says: Please use:

JVM 1.6.0_27 说:请使用:

  • CMSClassUnloadingEnabled(Whether class unloading enabled when using CMS GC)
  • in place of CMSPermGenSweepingEnabledin the future
  • CMSClassUnloadingEnabled(使用 CMS GC 时是否启用类卸载)
  • 代替CMSPermGenSweepingEnabled将来

See the full Hotspot JVM Options - The complete referencefor mroe.

请参阅完整的Hotspot JVM 选项 -mroe的完整参考

回答by Ondra ?i?ka

If you see this when running mvn jetty:run, set the MAVEN_OPTS.

如果您在运行时看到此信息 mvn jetty:run,请将MAVEN_OPTS.

For Linux:

对于 Linux:

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

For Windows:

对于 Windows:

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

Should be fine now. If not, increase -XX:MaxPermSize.

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

You can also put these permanently to your environment.

您还可以将这些永久放置到您的环境中。

回答by col

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.

这是因为按照您的建议重新加载了类。如果您使用大量库等,每次重新启动时类的总和会迅速增加。尝试使用 VisualVM 监控您的码头实例,以了解重新加载时的内存消耗情况。

回答by Jorge Ortiz

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.

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

回答by Miguel Ping

The permanent generation is where the JVM puts stuff that will probably not be (garbage) collected like custom classloaders.

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

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.

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

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):

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

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

The other option is to make sure that either the container or the framework do not leak memory.

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