为什么我的Java堆转储仅显示堆的一半?

时间:2016-04-09 14:08:09

标签: java heap-memory

我故意在数据结构中添加项目,直到Java抛出OutOfMemoryError,并使用-XX:+HeapDumpOnOutOfMemoryError获取堆转储。我使用-Xmx100M,所以我预计堆转储会显示近100MB的活动对象,但它只显示46MB。

如果只有46MB的活动对象,为什么Java会抛出100MB堆的OOM?

(我意识到我很难有机会提供足够的信息来回答这个问题,但我不确定相关的内容。很高兴根据需要添加更多信息。 )

编辑:-verbose:gc输出结束:

 [Full GC (Ergonomics) [PSYoungGen: 1056K->64K(2560K)] [ParOldGen: 7116K->7116K(7168K)] 8173K->7180K(9728K), [Metaspace: 5981K->5981K(1056768K)], 0.0071141 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
 [Full GC (Allocation Failure) [PSYoungGen: 64K->0K(2560K)] [ParOldGen: 7116K->7075K(7168K)] 7180K->7075K(9728K), [Metaspace: 5981K->5974K(1056768K)], 0.0190392 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
 java.lang.OutOfMemoryError: Java heap space

1 个答案:

答案 0 :(得分:4)

堆分为年轻一代和老一代两部分。例如,你得到OOM老一代是完整的或支离破碎的,以至于不可能将年轻一代的对象推向旧的(可能是其他人)。

如果您使用例如日志记录GC使用情况-verbose:gc -XX:+PrintGCDetails -Xloggc:gc.log然后你会看到每一代的尺寸。

您可以在此处查看如何调整生成大小https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/sizing.html