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

如何在JVM中统计某个类所有实例的总占用大小?

获取JVM中指定类所有实例的总大小

核心现状与问题

你已经通过JVM Tool Interface(JTI)相关API拿到了目标类的所有ObjectReference实例列表:

List<ReferenceType> classes = vm.classesByName(klass.getName());
List<ObjectReference> objectReferences = classes.get(0).instances(Long.MAX_VALUE);

但这里的ObjectReference是JTI抽象的跨虚拟机对象代理引用,无法直接转换为本地JVM堆中的实际Object实例,因此不能直接传给JOL的VM.current().sizeOf()方法计算大小。

可行解决方案

方案1:通过JTI直接计算浅大小

ObjectReference本身提供了获取对象浅大小的方法,无需转换为本地对象:

long totalShallowSize = 0;
for (ObjectReference objRef : objectReferences) {
    totalShallowSize += objRef.getSize();
}

此方法返回的是对象自身占用的内存(不包含其引用的其他对象),如果需要统计保留大小(对象被回收时可释放的总内存,包含其独有引用的对象),则需要自行实现引用链遍历与可达性分析逻辑,排除被其他对象共享引用的部分。

方案2:基于堆转储统计精确大小

如果需要更全面的保留大小统计,可通过JTI生成堆转储后离线分析:

  1. 生成目标JVM的堆转储文件:
File dumpFile = Files.createTempFile("heapdump", ".hprof").toFile();
vm.dumpHeap(dumpFile.getAbsolutePath(), true);
  1. 使用堆解析逻辑(可基于开源堆分析库或自行实现HProf格式解析)读取堆转储,统计指定类所有实例的浅大小或保留大小。

IDE实现原理参考

Eclipse和IntelliJ IDEA的内存分析功能,核心逻辑与上述方案一致:

  • 浅大小直接通过JTI的ObjectReference.getSize()获取;
  • 保留大小则是通过遍历对象引用图,标记仅由目标类实例引用的对象,再汇总这些对象的总大小,本质是实现了简化版的垃圾回收可达性分析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:31:03