jmap使用详解

jmap 是一个 Java 内存映像工具,用于生成 Java 应用程序的堆转储文件(heap dump)并查看对象内存占用情况,还可以分析 JVM 的垃圾收集器行为。它在排查内存泄漏、查看对象分布以及分析内存占用问题时非常有用。

基本用法

jmap [options] <pid>
  • pid:Java 进程的进程号。可以通过 jpsps 或者其他系统工具查看。

常用选项

  1. -heap
    显示 Java 堆内存的详细信息,包括堆大小、使用情况和垃圾收集器的相关信息。可以用于查看堆内存分代(年轻代、老年代等)使用的状态。

    jmap -heap <pid>
    

    输出示例

    Attaching to process ID 12345, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.141-b15
    
    using parallel threads in the new generation.
    using thread-local object allocation.
    Concurrent Mark-Sweep GC
    
    Heap Configuration:
       MinHeapFreeRatio         = 0
       MaxHeapFreeRatio         = 100
       MaxHeapSize              = 2147483648 (2048.0MB)
       NewSize                  = 1310720 (1.25MB)
       MaxNewSize               = 17592186044415 MB
       OldSize                  = 5439488 (5.1875MB)
       MetaspaceSize            = 21807104 (20.796875MB)
       CompressedClassSpaceSize = 1073741824 (1024.0MB)
       ...
    
    Heap Usage:
    New Generation (Eden + 1 Survivor Space):
       capacity = 603979776 (576.0MB)
       used     = 49638784 (47.33973693847656MB)
       free     = 554340992 (528.6602630615234MB)
    ...
    
    • Heap Configuration:显示 JVM 堆的配置,包括最小和最大堆大小、年轻代和老年代的大小、Metaspace(元空间)的配置等。
    • Heap Usage:显示堆内存的使用情况,特别是新生代、老年代的内存占用。
  2. -histo
    输出堆中各类 Java 对象的统计信息(对象的类型、数量和大小)。可以用于分析哪个类的对象数量最多,占用内存最大。

    jmap -histo <pid>
    

    输出示例

    num     #instances         #bytes  class name
    ----------------------------------------------
    1:           10000        2400000  [C
    2:            5000        1200000  java.lang.String
    3:            4000         960000  java.util.ArrayList
    ...
    
    • #instances:每个类的对象实例数量。
    • #bytes:这些对象占用的内存大小。
    • class name:对象所属的类。

    通过 -histo 选项,可以快速查看哪些对象占用了大量内存,在排查内存泄漏时非常有用。

  3. -dump
    生成 JVM 堆的转储文件(heap dump),通常用于分析内存泄漏。生成的堆转储文件可以使用分析工具如 Eclipse MAT(Memory Analyzer)进行深入分析。

    jmap -dump:format=b,file=<file_path> <pid>
    
    • format=b:指定堆转储文件的格式为二进制(默认格式)。
    • file=<file_path>:指定转储文件的保存路径。

    示例

    jmap -dump:format=b,file=/tmp/heapdump.hprof 12345
    

    这个命令会将 Java 进程 12345 的堆内存导出到 /tmp/heapdump.hprof 文件中。

  4. -finalizerinfo
    显示正在等待 finalization 队列中的对象。这些对象已经被垃圾收集器标记为可回收,但在它们的 finalize() 方法执行之前不会被清除。

    jmap -finalizerinfo <pid>
    

    这个命令有助于分析垃圾回收延迟的问题,特别是当大量对象未及时清除时,可以检查是否有大量对象在等待 finalize 处理。

  5. -F
    强制执行命令,即使目标 JVM 没有响应或出现问题时也强制获取相关信息。该选项通常与 -dump-histo 结合使用。

    jmap -dump:format=b,file=heapdump.hprof -F <pid>
    
  6. -clstats
    显示类加载器的统计信息,包括每个类加载器加载的类数量、字节数等。这对于调试类加载器泄漏或内存占用问题非常有用。

    jmap -clstats <pid>
    

使用场景

1. 内存泄漏排查

内存泄漏是 Java 程序中常见的问题之一,通过 jmap 可以获取堆转储(heap dump)文件,并结合其他工具(如 Eclipse MAT)进行详细分析。常用步骤如下:

  1. 使用 jmap -dump:format=b,file=heapdump.hprof <pid> 生成堆转储文件。
  2. 使用内存分析工具(如 MAT)加载 heapdump.hprof 文件,分析对象的占用情况、GC Roots 等,找出内存泄漏源头。
2. 对象分布和内存使用分析

通过 jmap -histo <pid>,可以查看当前 Java 堆中各类对象的数量和内存占用情况。如果某类对象占用了大量内存且不断增长,可能说明该类存在内存泄漏或过多分配。

3. 垃圾回收行为调优

通过 jmap -heap <pid>,可以查看 JVM 堆内存的详细使用情况和垃圾收集器的配置。在内存使用异常时(如频繁 Full GC),可以通过该命令了解各代内存的占用情况,帮助调整垃圾收集器的参数。

4. 检查 finalize() 延迟执行

通过 jmap -finalizerinfo <pid> 可以检查 finalize() 方法是否因为某种原因延迟执行,导致对象无法及时回收。如果有大量对象排队等待 finalize(),可能说明有资源释放方面的问题。

结合 jmap 与其他工具

  1. Eclipse MAT(Memory Analyzer Tool)
    用于分析通过 jmap -dump 生成的堆转储文件,MAT 可以帮助你找到哪些对象占用的内存最多,以及是否存在内存泄漏。

  2. jstack
    可以结合 jstack 分析线程状态。某些情况下内存泄漏可能与线程阻塞或死锁相关,通过同时查看线程快照和堆转储文件可以帮助全面分析问题。

注意事项

  • 性能影响:在高负载的生产环境中使用 jmap -dump 生成堆转储文件时,可能会导致应用短暂挂起,因此在生产环境中使用时需要小心,通常建议在低负载或预生产环境下执行。

  • 堆转储文件较大:堆转储文件(.hprof)通常非常大,特别是在大内存场景下生成的文件可能会达到数百 MB 或数 GB,因此要确保有足够的磁盘空间。

  • 权限问题:在某些系统中,使用 jmap 可能需要以 root 或具有足够权限的用户身份运行,否则会报权限错误。

总结

jmap 是 JVM 内存分析的重要工具,特别适用于以下场景:

  • 内存泄漏排查:通过堆转储文件和对象分布查看是否有类占用过多内存。
  • 垃圾回收调优:通过查看堆内存使用情况了解 GC 行为和内存分代配置。
  • 检查对象的分配和清除:分析等待 finalize 的对象,检查对象分配是否异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

测试不打烊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值