在 JVM 引发异常后,我正在分析一些堆转储OutOfMemory
。我在 Windows 2008R2 平台上使用 Hotspot JDK 1.7(64 位)。应用服务器是一个 JBoss 4.2.1GA,通过 Tanuki Java Service Wrapper启动。
它使用以下参数启动:
wrapper.java.additional.2=-XX:MaxPermSize=256m
wrapper.java.initmemory=1498
wrapper.java.maxmemory=3000
wrapper.java.additional.19=-XX:+HeapDumpOnOutOfMemoryError
翻译为:
-Xms1498m -Xmx3000m -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError
还有一些其他的 GC & JMX 配置参数。
我的问题是,当我分析由于OutOfMemoryException
使用Eclipse Memory Analyzer而创建的堆转储时,MAT 总是向我显示 2.3G 或 2.4G 的堆大小。我已经在 MAT 中启用了该选项Keep Unreachable Objects
,所以我不相信 MAT 正在修剪堆。
java.lang.RuntimeException: java.lang.OutOfMemoryError: GC overhead limit exceeded
或者
java.lang.OutOfMemoryError: Java heap space
MAT总结:
Size: 2.3 GB Classes: 21.7k Objects: 47.6m Class Loader: 5.2k
我的实际堆文件大小约为 3300KB,因此它们符合我的 3000m 最大堆大小设置。
那么MAT中缺少的500-600M内存在哪里呢?为什么 MAT 只显示我的堆大小为 2.4G?
SO上的其他帖子倾向于表明它是JVM在转储堆之前进行了一些GC,但是如果缺少500M是由于GC,为什么它甚至首先抛出OOM?如果 GC 真的可以清理 500M(或者我的堆的近 25%),那么 JVM 真的内存不足吗?
有没有办法调整堆转储,以便我可以获得堆的完整/完整图片(包括丢失的 500M)?
如果不是,我发现我真的很难找到我首先遇到这些 OOM 的方式/原因。
根据某人的要求,我附上了jstat -gc <PID> 1000
来自活动节点的输出:http: //pastebin.com/07KMG1tr。