Glassfish DAS OutOfMemory,总堆使用率低于最大堆大小

时间:2012-03-16 19:45:46

标签: jvm glassfish heap performance out-of-memory

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

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

不幸的是,错误发生在几个星期前,机器已经重新启动,因此我可能丢失了一些上下文信息。我正在寻找提示或解释,并试图防止这些错误。提前感谢您的帮助。

欢呼声

/萨姆

1 个答案:

答案 0 :(得分:0)

  

我的问题是:为什么JVM在输出OOM错误之前没有增加堆大小?

使用您设置的JVM选项( -Xmx2048m ),最大堆空间将是2G,这是正确的,但您没有设置初始堆空间选项 -Xms1024
此选项将告诉JVM最初为服务器提供1024MB的堆空间,而不是在需要时缓慢增加它。

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

请查看this以调整您的应用服务器。

关于你的MemLeaks:
很难判断这些是真正的内存泄漏还是只是某些服务器类 要检查这一点,您可以触发内存转储并进行分析,例如MemoryAnalyser

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