java如何查看堆中对象的统计信息?
在 Java 中查看堆中对象的统计信息(如实例数量、内存占用等),主要有以下几种方法:
1. 使用 JDK 命令行工具
(1) jmap + jhat/jvisualvm
步骤:
# 1. 生成堆转储文件(Heap Dump)
jmap -dump:live,format=b,file=heapdump.hprof <pid>
# 2. 使用 jhat 分析堆转储(默认端口 7000)
jhat heapdump.hprof
# 浏览器访问 http://localhost:7000
# 或使用图形化工具 jvisualvm 分析
jvisualvm -> 文件 -> 装入 -> 选择 heapdump.hprof
(2) jcmd
(JDK 7+ 推荐)
# 直接打印堆中对象直方图(按类统计实例数和内存)
jcmd <pid> GC.class_histogram
(3) jmap
直方图
jmap -histo:live <pid> # 统计存活对象
jmap -histo <pid> # 统计所有对象
输出示例:
num #instances #bytes class name ------------------------------------------- 1: 1000000 20000000 java.lang.String 2: 500000 15000000 [Ljava.lang.Object;
2. 使用图形化工具
(1) JVisualVM
-
启动:
jvisualvm
-
连接目标进程 -> 切换到 监视 标签
-
点击 堆 Dump -> 在 对象 标签页查看统计信息
(2) Eclipse MAT (Memory Analyzer Tool)
-
打开
heapdump.hprof
文件 -
查看 Histogram 或 Dominator Tree
(3) JConsole
-
启动:
jconsole
-
连接进程 -> 切换到 内存 标签
-
可查看堆内存概览(但无详细对象统计)
3. 编程方式(通过 JMX)
通过 Java 代码获取堆对象直方图:
import javax.management.*;
import java.lang.management.*;
public class HeapHistogram {
public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName hotspot = new ObjectName("com.sun.management:type=HotSpotDiagnostic");
Object[] params = { null, true }; // (className, includeSubclasses)
String[] sig = { "java.lang.String", "boolean" };
// 调用 getObjectHistogram 方法
CompositeDataSupport histogram = (CompositeDataSupport) mbs.invoke(
hotspot, "getObjectHistogram", params, sig
);
// 解析并打印结果
CompositeData[] elements = (CompositeData[]) histogram.get("elements");
for (CompositeData cd : elements) {
String className = (String) cd.get("className");
long count = (Long) cd.get("count");
long size = (Long) cd.get("size");
System.out.printf("%-50s | Count: %-8d | Size: %d KB\n",
className, count, size / 1024);
}
}
}
4. 开启 Native Memory Tracking (NMT)
适用于跟踪 JVM 内部内存(非堆对象):
# 启动时添加参数
java -XX:NativeMemoryTracking=summary ...
# 查看统计
jcmd <pid> VM.native_memory summary
关键注意事项:
-
-histo:live
或GC.class_histogram
会触发 Full GC,生产环境慎用。 -
堆转储(Heap Dump)会暂停应用,文件较大(建议在测试环境操作)。
-
推荐工具:
-
快速诊断:
jcmd <pid> GC.class_histogram
-
深度分析:Eclipse MAT
-
-
编程方式需要
com.sun.management
模块支持(Oracle/OpenJDK 可用)。
选择合适的方法根据你的需求(实时性、详细程度、是否生产环境)来决定。