通过 getMemoryMXBean() 和 jvisualvm 获得的内存使用量之间的差异?

Posted

技术标签:

【中文标题】通过 getMemoryMXBean() 和 jvisualvm 获得的内存使用量之间的差异?【英文标题】:Discrepancy between memory usage got through getMemoryMXBean() and jvisualvm? 【发布时间】:2013-02-20 20:39:33 【问题描述】:

当试图通过以下代码监控我自己的程序的内存使用情况时

public static String heapMemUsage() 

    long used = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed();
    long max = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax();
    return ""+used+" of "+max+" ("+ used/(double)max*100.0 + "%)";

我得到的结果与通过 jvisualvm 看到的略有不同(我的程序中的17 588 616 与 jvisualvm 中的18 639 640)。我知道这没什么大不了的,但它确实让我思考。

这个事实有什么解释吗?

如果可能的话,我想使用编码版本,但如果它的结果​​在某种程度上有偏差,jvisualvm 在某种程度上更可信,我将不得不坚持使用 jvisualvm。

谢谢

【问题讨论】:

我想知道 jvisualvm 是否将堆和非堆内存使用量相加以获得它的数量。尝试将它们都添加到您的应用中,看看是否更接近。 【参考方案1】:

VisualVM 确实使用相同的方法来获取所需的值,让我们检查一下MonitoredDataImpl.java:

MonitoredDataImpl(Jvm vm,JmxSupport jmxSupport,JvmMXBeans jmxModel) 
    //...
    MemoryUsage mem = jmxModel.getMemoryMXBean().getHeapMemoryUsage();
    MemoryPoolMXBean permBean = jmxSupport.getPermGenPool();    
    //...
    genCapacity = new long[2];
    genUsed = new long[2];
    genMaxCapacity = new long[2];
    genCapacity[0] = mem.getCommitted();
    genUsed[0] = mem.getUsed();

    genMaxCapacity[0] = mem.getMax();

    if (permBean != null) 
        MemoryUsage perm = permBean.getUsage();
        genCapacity[1] = perm.getCommitted();
        genUsed[1] = perm.getUsed();
        genMaxCapacity[1] = perm.getMax();
    
  

所以无论如何使用你的方法是安全的。请发布有关 JVM 版本等的附加信息以跟踪此问题。

【讨论】:

以上是关于通过 getMemoryMXBean() 和 jvisualvm 获得的内存使用量之间的差异?的主要内容,如果未能解决你的问题,请参考以下文章

Angularfire:如何通过其中一个属性访问项目?

JV的DOM操作

W25Q128BV W25Q128FV W25Q128JV 什么区别?

javascript Formulářjakoobjekt - můjvýtvor

JV默认是如何处理异常

两个字段的SQL总和