jcmd和java.lang.management.MemoryUsage报告的伊甸园空间使用率值之间的差异

时间:2019-05-13 19:24:11

标签: java memory-management

我想使用java.lang.management.MemoryUsage监视代码的堆使用情况。在下面的示例中,我在HashSet中创建了一堆条目,然后检查堆的使用情况。我期望看到的伊甸园空间内存使用非零值。令我惊讶的是,我发现伊甸园空间使用量为零,幸存者空间使用量为非零。 这与jcmd命令打印的堆信息值不匹配,后者显示eden空间的使用非零。 有人可以帮我理解背后的原因吗?

我正在使用Linux上的OpenJDK 11.0.2的ParllelOldGC(-XX:+ UseParallelOldGC)。

我尝试在各种论坛上进行搜索,但是找不到相关信息。

public HeapUsage() {
    System.out.println("Before ");
    printHeapUsage();
    HashSet<String> set = new HashSet<>();
    for (int i = 0; i<10000000; i++) {
        set.add(String.valueOf(i));
    }
    System.out.println("After");
    printHeapUsage();

}
public static void main(String[] args) throws InterruptedException {
    new HeapUsage();
    Thread.sleep(1000000);
}

private void printHeapUsage() {
    for (MemoryPoolMXBean mpbean :
         ManagementFactory.getMemoryPoolMXBeans()) {
        MemoryUsage usage = mpbean.getCollectionUsage();
        if (usage != null) {
            long max = usage.getMax();
            long used = usage.getUsed();            
            System.out.println(mpbean.getName() + " Used " + used + ", Max " + max);
        }
    }
}

Java代码输出-

之前 PS Old Gen使用0,最大21473787904

已使用PS幸存者空间0,最大89128960

已使用PS Eden空间0,最大10558111744

之后

PS Old Gen Used 0,最大21473787904

已使用PS幸存者空间89096256,最大89128960

已使用PS Eden空间0,最大10558111744

jcmd输出-

jcmd 45766 GC.heap_info 45766:  PSYoungGen总611840K,已用541937K [0x0000000580100000,0x00000005cac00000,0x0000000800000000)

eden空间524800K,已使用86% [0x0000000580100000,0x000000059bd44778,0x00000005a0180000)

从空间87040K,已使用99%[0x00000005a0180000,0x00000005a5678040,0x00000005a5680000)

到空间87040K,已用0%[0x00000005c5700000,0x00000005c5700000,0x00000005cac00000)

ParOldGen总计1398272K,已用385048K [0x0000000080200000、0x00000000d5780000、0x0000000580100000)

对象空间1398272K,已使用27%[0x0000000080200000,0x0000000097a06000,0x00000000d5780000)

已使用元空间6287K,容量6411K,已提交6656K,保留1056768K

使用的类空间为586K,容量为653K,已提交768K,保留为1048576K

1 个答案:

答案 0 :(得分:0)

我应该仔细阅读Javadoc。 MemoryPoolMXBean.getCollectionUsage()在最近的垃圾回收之后返回内存使用量 。 GC后,伊甸园空间为空是正常的。 jcmd GC.heap_info给出了当前的堆使用情况(相当于MemoryPoolMXBean.getUsage()。因此,在此示例中,jcmd的输出与问题中代码段的输出不匹配。