java如何查看堆中对象的统计信息?

在 Java 中查看堆中对象的统计信息(如实例数量、内存占用等),主要有以下几种方法:


1. 使用 JDK 命令行工具

(1) jmap + jhat/jvisualvm

步骤:

bash
 
# 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+ 推荐)

bash
 
# 直接打印堆中对象直方图(按类统计实例数和内存)
jcmd <pid> GC.class_histogram

(3) jmap 直方图

bash
 
jmap -histo:live <pid>  # 统计存活对象
jmap -histo <pid>       # 统计所有对象

输出示例:

text
 
 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)

(3) JConsole

  • 启动:jconsole

  • 连接进程 -> 切换到 内存 标签

  • 可查看堆内存概览(但无详细对象统计)


3. 编程方式(通过 JMX)

通过 Java 代码获取堆对象直方图:

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 内部内存(非堆对象):

bash
 
# 启动时添加参数
java -XX:NativeMemoryTracking=summary ...

# 查看统计
jcmd <pid> VM.native_memory summary

关键注意事项:

  1. -histo:live 或 GC.class_histogram 会触发 Full GC,生产环境慎用。

  2. 堆转储(Heap Dump)会暂停应用,文件较大(建议在测试环境操作)。

  3. 推荐工具:

    • 快速诊断:jcmd <pid> GC.class_histogram

    • 深度分析:Eclipse MAT

  4. 编程方式需要 com.sun.management 模块支持(Oracle/OpenJDK 可用)。

选择合适的方法根据你的需求(实时性、详细程度、是否生产环境)来决定。

posted @ 2025-08-01 13:21  飘来荡去evo  阅读(58)  评论(0)    收藏  举报