如何获取Java中含GC回收对象的累计内存分配总字节数?
获取JVM累计内存分配总量(含GC回收对象)的实现方法
完全可以通过JDK自带的管理类实现这个需求,不需要额外引入第三方库。Runtime类无法直接获取累计分配量,但ManagementFactory搭配相关MXBean可以轻松做到。
核心实现思路
JVM的每个内存池(如Eden区、Survivor区、老年代)都会记录自身从启动以来的累计内存分配量,这个值包含了已经被GC回收的对象占用的内存。我们只需要遍历所有内存池,汇总它们的累计分配数据即可得到全局总量。
代码示例
import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; public class CumulativeMemoryAllocation { public static void main(String[] args) { long totalAllocated = 0; // 遍历所有内存池MXBean for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) { // 检查当前内存池是否支持累计分配量统计 if (pool.getTotalAllocatedBytes() != -1) { totalAllocated += pool.getTotalAllocatedBytes(); } } // 转换为更易读的MB单位输出 double totalMB = totalAllocated / (1024.0 * 1024.0); System.out.printf("累计内存分配总量(含GC回收对象):%d 字节 / %.2f MB%n", totalAllocated, totalMB); } }
关键说明
getTotalAllocatedBytes():返回对应内存池从JVM启动至今分配的总内存量,不管这些内存是否已被GC回收,完全符合需求。- 部分内存池可能不支持该统计(返回-1),所以需要做判断过滤。
- 对比
Runtime.totalMemory():这个方法返回的是JVM当前已从操作系统申请的内存大小,仅代表当前存活对象+未回收的内存,不是累计分配总量,无法满足需求。
注意事项
- 该方法基于JVM的管理API,在HotSpot、OpenJ9等主流JVM实现中均支持。
- 如果需要实时监控累计分配量,可以结合
NotificationListener监听内存池事件,或者定时轮询统计。
内容的提问来源于stack exchange,提问作者Bishal Ghosh
相关产品推荐
相关产品推荐

