You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无探查器获取JVM累计分配总内存?及代码正确性验证

你的代码分析与修正建议

咱们先直接说结论:你这段代码不能实现你想要的“当前节点已分配总内存”的需求,结果会有明显误导性,核心问题出在getPeakUsage()方法的使用上。

问题根源

getPeakUsage()返回的是对应内存池自JVM启动(或最后调用resetPeakUsage()重置峰值以来)达到过的最大内存使用量,而不是当前时刻的内存状态。举个例子:如果你的程序之前有过一次内存占用高峰,之后内存已经被释放了,这段代码算出来的还是那个高峰值,完全反映不了当前节点的真实已分配内存。

修正后的代码

要获取当前时刻的已分配总内存,你需要把getPeakUsage()替换为getUsage(),这才是内存池的当前实时内存使用情况。修改后的代码如下:

ManagementFactory.getMemoryPoolMXBeans()
    .stream()
    .map(MemoryPoolMXBean::getUsage)
    .filter(usage -> usage != null)
    .mapToLong(MemoryUsage::getUsed)
    .sum();

额外的细节说明

  • 区分getUsed()和getCommitted():
    • getUsed()是当前已经被Java对象占用的内存量(真正“已分配使用”的部分)
    • getCommitted()是JVM已经从操作系统申请到的总内存量(包含已使用和未被使用但已分配给JVM的部分)
      如果你要的是“JVM从系统拿到的所有已分配内存”,那把mapToLong(MemoryUsage::getUsed)改成mapToLong(MemoryUsage::getCommitted)即可。
  • 你代码里的filter(usage -> usage != null)很有必要,因为某些平台下的特定内存池可能会返回null的内存使用数据,这个过滤能避免空指针异常。
  • 如果只需要堆内存的整体情况,也可以用更简洁的方式:ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(),它直接返回整个堆的内存状态,不用遍历所有内存池,但遍历内存池能让你了解新生代、老年代等各个区域的详细内存使用。

内容的提问来源于stack exchange,提问作者Sina Madani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:50:09