0

在 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

4

2 回答 2

1

java.lang.OutOfMemoryError:超出 GC 开销限制

这并不一定意味着您的堆已满,请参阅此问答

java.lang.OutOfMemoryError:Java 堆空间

这并不意味着您的堆还剩下 0 个字节,这意味着无法满足分配请求。如果某些东西试图分配 600MB 并且只剩下 500MB,那么这将引发 OOME。

如果不是,我发现我真的很难找到我首先遇到这些 OOM 的方式/原因。

获取堆栈跟踪以查看执行相关分配的调用站点是否有任何可疑之处将是一个开始。或者你可以尝试增加堆大小,看看问题是否消失。

于 2016-06-06T16:55:07.067 回答
1

你用的是哪个GC?您可能缺少 Eden,尝试使用jstat - Java 虚拟机统计监控工具

于 2016-06-06T14:54:19.490 回答