2012-03-16 77 views
0

我在Glassfish V2.1 6实例群集配置(SLES 10 SP4,64位Suse Linux机器,19Gb RAM)中运行大型企业应用程序,DAS机器server.log显示一些“java.lang.OutOfMemoryError:Java堆空间”错误。从DAS” jvm.log显示堆使用情况报告:Glassfish DAS OutOfMemory,总堆使用率低于最大堆大小

Heap 
PSYoungGen  total 103488K, used 99840K [0x00002aab237c0000, 0x00002aab2a270000, 0x00002aab4e260000) 
    eden space 99840K, 100% used [0x00002aab237c0000,0x00002aab29940000,0x00002aab29940000) 
    from space 3648K, 0% used [0x00002aab29940000,0x00002aab29940000,0x00002aab29cd0000) 
    to space 4672K, 0% used [0x00002aab29de0000,0x00002aab29de0000,0x00002aab2a270000) 
PSOldGen  total 1398144K, used 1398143K [0x00002aaace260000, 0x00002aab237c0000, 0x00002aab237c0000) 
    object space 1398144K, 99% used [0x00002aaace260000,0x00002aab237bfe70,0x00002aab237c0000) 
PSPermGen  total 107200K, used 106931K [0x00002aaaae260000, 0x00002aaab4b10000, 0x00002aaace260000) 
    object space 107200K, 99% used [0x00002aaaae260000,0x00002aaab4accd98,0x00002aaab4b10000) 

从我们得到1.6GB的总堆空间上面(103488 + 1398144 + 107200 = 1608832〜1.6GB),即使允许的最大堆空间设置为2Gb(-XX:MaxPermSize = 512m -Xmx2048m)。那么我的问题是:为什么JVM在输出OOM错误之前不会增加堆大小?我们如何解释上面的堆报告?我在一个二进制文件堆MAT跑工具,并得到了2名泄漏嫌疑人:

Problem suspect #1 

One instance of "com.sun.jmx.mbeanserver.JmxMBeanServer" loaded by "<system class loader>" occupies 522,351,680 (34.12%) bytes. The instance is referenced by org.jvnet.glassfish.comms.admin.management.extensions.config.OverloadProtectionServiceConfigImpl @ 0x2aaacfe74ed0 , loaded by "com.sun.appserv.server.util.ASURLClassLoader @ 0x2aaace7fc630". The memory is accumulated in one instance of "java.util.HashMap$Entry[]" loaded by "<system class loader>". 

Keywords 
java.util.HashMap$Entry[] 
com.sun.appserv.server.util.ASURLClassLoader @ 0x2aaace7fc630 
com.sun.jmx.mbeanserver.JmxMBeanServer 

Problem suspect #2 

140,421 instances of "net.jxta.impl.endpoint.tcp.TcpMessenger", loaded by "com.sun.appserv.server.util.ASURLClassLoader @ 0x2aaace7fc630" occupy 735,809,464 (48.07%) bytes. These instances are referenced from one instance of "java.util.TimerTask[]", loaded by "<system class loader>" 

Keywords 
java.util.TimerTask[] 
com.sun.appserv.server.util.ASURLClassLoader @ 0x2aaace7fc630 
net.jxta.impl.endpoint.tcp.TcpMessenger 

不幸发生的错误在几个星期前,机器已重新启动,因为这样我可能已经失去了一些相关的背景信息。我正在寻找提示或解释,并尝试防止这些错误。预先感谢您的帮助。

欢呼

/萨姆

+0

实际的OOM错误在哪里?它看起来更像是你用完堆而不是堆内存。 – Preston 2012-03-17 01:08:46

回答

0

My question is then: why isn't the JVM increasing the heap size before outputting OOM errors?

随着你设置的JVM选项(-Xmx2048m)最大堆空间是2G,这就是正确的,但你没”设置初始堆空间选项-Xms1024
该选项会告诉JVM最初为服务器提供1024MB堆空间,而不是在需要时缓慢增加它。

这可能会阻止您获得OOM错误,因为有时由于GC,JVM不会注意到一些内存更改。

看看this来调整你的应用服务器。

关于你MemLeaks:
这是很难说,如果那些是真正内存泄漏或只是一些服务器类。
要检查这个,你可以触发一个内存转储并用例如MemoryAnalyser

希望这会有所帮助,玩得开心!

+0

我记下了这个初始堆大小参数(-Xms),一定要设置(最大堆大小值恕我直言)。你提出的评论:“因为有时JVM没有注意到由于GC而引起的一些内存变化”,但我担心。你有什么特定的错误参考可以查看吗?我还注意到GC和堆相关的JVM选项已为集群实例设置和调整,但仅部分在服务器(DAS)配置上进行了调整。感谢您的富有洞察力的回应。 – 2012-03-19 17:34:15

+0

你的权利,'-Xms'值应该被设置为'-Xmx'值。对不起,现在我手边没有任何参考资料(只是一个关于GC在多次重新部署后没有执行的bug跟踪器),但我可以推荐[this](http://docs.oracle.com/cd/E19316-01 /820-4343/abeic/index.html)和[this](http://www.jroller.com/agileanswers/entry/preventing_java_s_java_lang)有关调整特别是垃圾集合的文章。他们帮助我在我的环境中解决这个问题!干杯! – SimonSez 2012-03-19 18:49:53