JBoss的7,java.lang.OutOfMemoryError:PermGen的空间(JBos

2019-06-26 13:10发布

当CPU使用率发挥到极致,我打这个错误和JBoss需要重新启动( java.lang.OutOfMemoryError: PermGen space )。

我发现对老年人的JBoss版本增加了一个解决方案MaxPermSize 。 我想这同样适用于JBoss7。

其价值将是不够好,为了不再次面对什么问题? 有没有办法摆脱这个问题永远远(比如让说,使用不同的虚拟机像JRockit的)?

Answer 1:

由于出现这种情况后,多次重新部署它听起来就像你遇到了一个类加载器泄漏 ,一个常用的一种PermGen的泄漏 。

这些可爱的野兽发生,因为正常(非弱)由集装箱拥有的对象的对象引用的that're从应用类加载器加载的类的实例。 如果这些引用不取消部署清理还是有很强的参考链应用程序的类加载器,所以它不能被GC'd和加载的类不能被释放。

一个常见的原因是在必须添加应用程序类的非静态引用容器类的静态集合。

JBoss应用服务器7在其模块系统,防止类加载器泄漏一些相当强的规定,所以我很惊讶你已经成功地触发一个。 我还没有看到一个类加载器泄漏,因为我从Glassfish的搬到AS7。

提高MaxPermSize参数会买你一些时间,但它无法摆脱的问题。

你真的需要找出为何类加载器泄漏。 这样做是“好玩”。 你享受税收,间歇性故障和清洁淋浴,对不对? 请参阅第一面值的链接,一些博客是会得到你开始跟踪泄漏下来。 基本上,你要使用的VisualVM和OQL为引用挖你的应用程序的类加载器,或采取堆转储和使用jhat (JDK的一部分)来查找引用。 无论哪种方式,这个想法是要弄清楚在从应用服务器到你的类加载器通过应用程序类的实例的强引用链。

或者,它可以帮助把你的应用程序的副本,然后开始直到泄漏消失剥开它位。 如果它是由VisualVM的或其他监控连接到应用服务器虚拟机并关注是否PermGen的后两位或增加更多的部署/取消部署周期泄露你可以告诉。 考虑自动化部署/取消部署周期。 泄漏的原因缩小到您的应用程序和/或它的一个依赖的一小部分,并产生一个小的,独立的测试案例,然后提交,作为(a)上的JBoss AS 7的bug报告,因为据我所知这是停下来的意思这种情况发生和(b)这是持有该引用的罪魁祸首。

如果缩小的原因下降到捆绑的部署存档内,将其移动到一个JBoss AS 7模块可以采取照顾的问题的相关性。 为它创建一个JBoss模块,将其部署到modules AS7的目录,并通过您就可以添加一个依赖于您的部署Manifest.MF或通过jboss-deployment-structure.xml 。 见的AS7的类加载器的文件 。

这就是为什么Jigsaw项目已经被推迟的事实让我伤心。 Java 需要的是摆脱这种污物强大的模块系统。



Answer 2:

该VM参数为:

-XX:MaxPermSize=256M

只是使它足够大,你不打了极限。

从广义上讲,烫发根内存用于与类关联的对象和实习字符串。 除非你有很多使用不同类别的你应该不会用完。



Answer 3:

我们必须做同样的事情,不幸的VisualVM没有为我们做了。

我们结束了使用Eclipse的垫子来分析碰撞产生的堆转储,然后检查了leak suspects报告,告诉我们,有很多的ModuleClassLoader被泄露的情况。

点击总览标签中的一个实例,然后选择merge shortest paths to GC roots + exclude weak references给了我们罪魁祸首这是不允许这些ModuleClassLoader实例被GC'ed!

https://smalldata.tech/blog/2015/09/29/detecting-java-permgen-memory-leak



Answer 4:

为什么会发生?

该“PermGen的”错误发生,当Java虚拟机中运行出来的永久代内存。 回想一下,Java有一个代垃圾收集器,四代:伊甸园,年轻的,年老和永久的。 在伊甸园代,对象是非常短暂的,垃圾收集是快速和频繁。 年轻一代包括幸存的伊甸园代(或被推下至年轻,因为伊甸园一代是充满在分配的时间),在年轻一代的垃圾收集是那么频繁,但在相当定期仍然发生对象(前提是您的应用程序实际上做一些事情,并分配对象现在每然后)。 老一代人,那么,你想通了。 它包含了幸存下来的年轻一代,或者已经被按下对象,垃圾收集就更加不罕见,但仍可能发生。 最后,永久代。 这是虚拟机已决定永生认可的对象 - 这是precicely问题的核心。 在永久代对象不会被垃圾收集; 也就是说,在正常情况下,当JVM启动正常的命令行参数。 因此,当您重新部署Web应用程序,你的WAR文件解压后是和它的类文件加载到JVM中会发生什么。 而这里的事:总是在永久代结束了......(摘自: http://rlogiacco.blogspot.com/2009/02/jboss-and-permgen-outofmemoryerror.html )

下面是一些建议:

使用此参数为您的JVM。 他们告诉垃圾收集器还援引其算法PermGen的。

set JAVA_OPTS=-Xms512m -Xmx1024m 
-XX:PermSize=512m 
-XX:MaxPermSize=1024m 
-XX:+UseConcMarkSweepGC 
-XX:+CMSPermGenSweepingEnabled 
-XX:+CMSClassUnloadingEnabled 
  • CMSPermGenSweepingEnabled设置包括在垃圾收集运行PermGen的。 默认情况下,PermGen的空间决不会被列入垃圾收集(因此没有增长边界)。
  • CMSClassUnloadingEnabled设置告诉PermGen的垃圾收集清扫采取类对象的动作。 默认情况下,类对象获得豁免,即使garabage收集过程中被访问PermGen的空间。

重新启动JBOSS,因为每次部署应用程序时,你增加PermGen的数据量。

您还可以使用的Jrocket JVM而非Sun JVM的。 它并没有在它的垃圾收集算法的任何PermGen的。



文章来源: JBoss 7, java.lang.OutOfMemoryError: PermGen space