【Java可执行命令】(二十)堆转储快照文件及堆信息查看工具 jmap:生成多格式堆转储文件、打印类加载器信息及查看共享对象映射信息 ~

本文介绍了Java开发工具jmap的概念、优势和缺点,展示了如何使用jmap生成堆转储文件、查看内存使用情况和打印对象统计信息,以及其在内存分析和性能优化中的应用。特别提到了MAT工具作为jmap的补充,用于深入分析内存问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述


1️⃣ 概念

jmapJava Development Kit(JDK)自带的一个工具,用于生成Java堆转储文件(Heap Dump)。它的设计目的是为了帮助开发人员分析和调试Java应用程序在运行时产生的内存问题。

jmap 命令可以通过连接到运行中的Java进程,生成指定类型的Java堆转储文件。Java堆转储文件是应用程序在特定时间点的内存快照,记录了Java虚拟机中对象的详细信息、引用关系以及当前内存使用情况。

jmap可以生成多种格式的Java堆转储文件,包括二进制格式(默认)、文本格式和HPROF二进制格式,它支持在特定的进程ID下生成堆转储文件,也支持对远程虚拟机进行操作。
同时,jmap还提供了一些额外的选项,如打印类加载器信息、查看共享对象映射等。

jmap命令通过Java虚拟机提供的 HotSpot Diagnostic 接口,连接到正在运行的Java进程,并请求生成Java堆转储文件。它使用Java虚拟机的Heap Dumper功能收集堆内对象的详细信息,并保存到指定的输出文件中。

2️⃣ 优势和缺点

优点:

  • 提供了一种快速生成Java堆转储文件的方式,方便开发人员获取内存快照;
  • 可以生成各种格式的堆转储文件,如二进制格式、文本格式等,满足不同需求;
  • 在处理大型堆转储文件时,jmap 的性能表现较好。

缺点:

  • jmap 需要连接到正在运行的Java进程,如果权限不足或者连接失败,可能无法使用该命令;
  • 处理大型堆转储文件时,可能会占用较多的系统资源,包括CPU和内存;
  • jmap 生成的堆转储文件可能过于庞大,需要额外的工具来分析和解读。

3️⃣ 使用

3.1 语法格式

jmap 命令的使用语法如下:

Usage:
    jmap [option] <pid>
        (to connect to running process)(连接到正在运行的进程)
    jmap [option] <executable <core>
        (to connect to a core file)(连接到核心文件)
    jmap [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)(连接到远程调试服务器)

其中,[option] 是可选的一些命令参数选项,<pid> 是Java进程的进程ID。对于命令中可选参数汇总如下:

参数说明
<none>打印与Solaris pmap相同的信息
-heap打印Java堆摘要信息
-histo[:live]打印Java堆对象的直方图;如果指定"live"子选项,则只计算存活对象
-clstats打印类加载器统计信息
-finalizerinfo打印等待终止的对象信息
-dump:<dump-options>hprof二进制格式导出Java堆。转储选项<dump-options>
live:仅转储活动对象;如果没有指定,堆中的所有对象都被转储;
format=b 二进制格式;
file=<file> 将堆转储到<file>
示例:jmap-dump:live,format=b,file=heap.bin<pid>
-F强制操作。与-dump:<dump-options> <pid>-histo一起使用,当不响应时强制执行堆转储或直方图。此模式不支持"live"子选项
-h | -help打印帮助信息
-J<flag>将参数直接传递给运行时系统

如果生成的堆转储文件过大,可以考虑使用压缩格式(如gzip)进行存储,以减少其占用空间。对于大型堆转储文件,可以使用 jhat 或其他分析工具来进一步解读和分析。

3.2 生成堆转储文件

jmap -dump:format=b,file=heapdump.hprof <pid>

上述命令会生成一个二进制格式的Java堆转储文件。如下图所示:

在这里插入图片描述
在这里插入图片描述

3.3 执行jmap命令查看内存使用情况

jmap -heap <pid>

运行上述命令可以输出Java堆的内存使用情况摘要信息,包括堆配置、空闲和已使用空间等。输出结果:

Attaching to process ID 172832, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.202-b08

using thread-local object allocation.
Parallel GC with 10 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 2099249152 (2002.0MB)
   NewSize                  = 44040192 (42.0MB)
   MaxNewSize               = 699400192 (667.0MB)
   OldSize                  = 88080384 (84.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 33554432 (32.0MB)
   used     = 4710360 (4.492149353027344MB)
   free     = 28844072 (27.507850646972656MB)
   14.03796672821045% used
From Space:
   capacity = 5242880 (5.0MB)
   used     = 0 (0.0MB)
   free     = 5242880 (5.0MB)
   0.0% used
To Space:
   capacity = 5242880 (5.0MB)
   used     = 0 (0.0MB)
   free     = 5242880 (5.0MB)
   0.0% used
PS Old Generation
   capacity = 88080384 (84.0MB)
   used     = 0 (0.0MB)
   free     = 88080384 (84.0MB)
   0.0% used

3162 interned Strings occupying 259504 bytes.

这个执行结果显示了与Java堆配置和使用相关的信息。下面是对每个部分的解释:

  1. Attaching to process ID 172832, please wait...:正在连接到进程ID为172832的进程,请稍等…
  2. Debugger attached successfully.:成功附加调试器。
  3. Server compiler detected.:检测到服务器编译器。说明正在使用JVM的C2(客户端编译器)进行即时编译。
  4. JVM version is 25.202-b08:JVM版本号为25.202-b08。

接下来是Java堆的配置信息:

  1. using thread-local object allocation.:使用线程本地对象分配。
  2. Parallel GC with 10 thread(s):采用并行GC(垃圾收集器),共有10个线程。

Heap Configuration 部分列出了Java堆的配置设置,包括以下目录:

  1. MinHeapFreeRatio:最小的可用于自由空间的堆比例。
  2. MaxHeapFreeRatio:最大的可用于自由空间的堆比例。
  3. MaxHeapSize:堆的最大大小。
  4. NewSize:新生代的初始大小。
  5. MaxNewSize:新生代的最大大小。
  6. OldSize:老年代的初始大小。
  7. NewRatio:新生代与老年代的比例。
  8. SurvivorRatio:Eden区和Survivor区的比例。
  9. MetaspaceSize:元空间(Metaspace)的初始大小。
  10. CompressedClassSpaceSize:压缩类空间的大小。
  11. MaxMetaspaceSize:元空间的最大大小。
  12. G1HeapRegionSize:使用G1收集器时的堆区域大小。

Heap Usage 部分显示了Java堆的使用情况,包括各个区域的容量、已用空间和空闲空间:

  1. PS Young Generation:表示Parallel Scavenge GC中的新生代(Parallel Scavenge是一种垃圾收集器)
  2. Eden Space:伊甸园区域的容量、已用空间和空闲空间。
  3. From Space:幸存者(Survivor)区中的From区域的容量、已用空间和空闲空间。
  4. To Space:幸存者(Survivor)区中的To区域的容量、已用空间和空闲空间。
  5. PS Old Generation:表示Parallel Scavenge GC中的老年代。
  6. capacity:容量。
  7. used:已使用的空间。
  8. free:可用的空闲空间。
  9. 最后一行 3162 interned Strings occupying 259504 bytes.:表示共有3162个interned字符串占用了259504字节的内存。

这些信息提供了有关Java堆配置和使用情况的详细数据,可用于分析和优化应用程序的内存使用。

3.4 执行jmap命令打印对象统计信息

jmap -histo <pid>

上述命令会输出Java堆中各个类的实例数目和内存占用情况,可以帮助开发人员了解应用程序的内存使用情况。输出结果:


 num     #instances         #bytes  class name
----------------------------------------------
   1:           660        2093048  [I
   2:          1185        1171784  [B
   3:          7723         910880  [C
   4:          5893         141432  java.lang.String
   5:           691          78976  java.lang.Class
   6:          1294          60888  [Ljava.lang.Object;
   7:           791          31640  java.util.TreeMap$Entry
   8:           628          25120  java.util.LinkedHashMap$Entry
   9:           456          22144  [Ljava.lang.String;
  10:           365          11680  java.util.HashMap$Node
  11:            38          11584  [Ljava.util.HashMap$Node;
  12:           152          10944  java.lang.reflect.Field
  13:           435          10440  java.lang.StringBuilder
  14:           242           7744  java.util.Hashtable$Entry
  15:           233           7456  java.io.File
  16:           101           6464  java.net.URL
  17:           241           5784  java.lang.StringBuffer
  18:           125           5000  java.lang.ref.SoftReference
  19:           258           4128  java.lang.Integer
  20:           115           3680  java.util.concurrent.ConcurrentHashMap$Node
  21:            25           3648  [Ljava.util.Hashtable$Entry;
  22:            72           3456  java.nio.HeapCharBuffer
  23:            71           3408  java.nio.HeapByteBuffer
  24:            42           3360  [S
  25:             8           3008  java.lang.Thread
  26:             5           2568  [J
  27:            20           2496  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  28:            44           2464  sun.misc.URLClassPath$JarLoader
  29:             2           2384  [[Ljava.lang.Object;
  30:            89           2136  java.net.Parts
  31:             2           2080  [[C
  32:            26           2080  java.lang.reflect.Constructor
  ...
 369:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total         23572        4710360

这个执行结果是一个对象直方图,列出了不同类的实例数量和占用的内存大小。下面是对每个列的解释:

  1. num:序号,表示第几行。
  2. #instances:实例数量,表示内存中存在多少个该类的实例。
  3. #bytes:内存大小,表示该类实例所占用的总字节数。
  4. class name:类名,表示相应实例的类名。

接下来的表格显示了一系列对象的统计数据,从最多实例到最少实例进行排序。其中每一行对应一个类的统计信息。

例如,在第4行:

  • 4: 5893 141432 java.lang.String
    表示有5893个java.lang.String类的实例,占用141,432字节的内存。

最后一行 Total 23572 4710360 表示总共有23,572个对象实例,占用4,710,360字节的内存。

通过分析对象直方图,可以了解系统中不同类型的对象的创建情况和内存消耗,从而帮助开发人员找到内存相关的问题,并进行性能优化和内存管理。

4️⃣ 应用场景

  • 分析Java应用程序的内存使用情况,包括堆大小、对象数量、内存泄漏等问题;
  • 为内存相关的性能调优提供数据支持,比如查找常驻内存的对象、优化内存分配等;
  • 在应用程序出现内存溢出或性能问题时,生成堆转储文件进行进一步分析和定位问题。

需要注意,jmap 需要操作系统级别的权限来连接到正在运行的Java进程,需要确保当前用户有足够的权限。在处理大型堆转储文件时,可能会占用较多的系统资源,请确保足够的CPU和内存。
而如果生成的堆转储文件非常庞大时,需要使用专门的工具(如 jhatMAT等)进行解读和分析。

MAT(Memory Analyzer Tool)是一个Java堆分析器,它是一款强大的开源工具,用于分析Java应用程序在运行时产生的内存问题。MAT可以帮助开发人员快速定位和解决内存泄漏、大对象占用过多内存、内存溢出等常见的内存相关问题。

MAT提供了多种功能和特性:

  1. 内存快照分析:可以加载并分析通过jmap或者其他工具生成的Java堆转储文件(如hprof格式),以获取详细的内存使用情况。
  2. 强大的查询和筛选功能:支持丰富的查询语言和过滤条件,方便开发人员查找特定类型的对象,快速定位问题所在。
  3. 可视化对象图:以直观的方式展示Java堆中的对象及其引用关系,帮助开发人员理解对象之间的关联,从而更好地排查内存问题。
  4. 内存报告和统计:生成详细的内存报告,包括对象数量、内存占用、GC根引用等统计信息,帮助开发人员分析对象的分布和趋势。
  5. 内存泄漏检测:自动检测可能造成内存泄漏的对象,识别存在潜在泄漏的代码路径,辅助开发人员修复内存问题。
  6. 快速分析和低内存占用:MAT具有高效的内存使用和分析性能,即使在处理大型堆转储文件时也能保持较低的内存占用。

🌾 总结

jmap命令是Java开发工具包(JDK)中的一个有用工具,用于生成Java堆转储文件以及查看堆和对象统计信息。通过连接到运行中的Java进程,jmap提供了快速生成内存快照的方式,帮助开发人员检测和调试Java应用程序的内存问题。然而,使用时需要注意权限、资源消耗以及处理生成的大型转储文件的需求。综上所述,jmap是一个强大的工具,适用于各种Java内存分析和调优的场景。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小山code

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

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

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

打赏作者

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

抵扣说明:

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

余额充值