Java可执行命令之jmap
- 1️⃣ 概念
- 2️⃣ 优势和缺点
- 3️⃣ 使用
- 3.1 语法格式
- 3.2 生成堆转储文件
- 3.3 执行jmap命令查看内存使用情况
- 3.4 执行jmap命令打印对象统计信息
 
 
- 4️⃣ 应用场景
- 🌾 总结

1️⃣ 概念
jmap 是 Java 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堆配置和使用相关的信息。下面是对每个部分的解释:
- Attaching to process ID 172832, please wait...:正在连接到进程ID为172832的进程,请稍等…
- Debugger attached successfully.:成功附加调试器。
- Server compiler detected.:检测到服务器编译器。说明正在使用JVM的C2(客户端编译器)进行即时编译。
- JVM version is 25.202-b08:JVM版本号为25.202-b08。
接下来是Java堆的配置信息:
- using thread-local object allocation.:使用线程本地对象分配。
- Parallel GC with 10 thread(s):采用并行GC(垃圾收集器),共有10个线程。
Heap Configuration 部分列出了Java堆的配置设置,包括以下目录:
- MinHeapFreeRatio:最小的可用于自由空间的堆比例。
- MaxHeapFreeRatio:最大的可用于自由空间的堆比例。
- MaxHeapSize:堆的最大大小。
- NewSize:新生代的初始大小。
- MaxNewSize:新生代的最大大小。
- OldSize:老年代的初始大小。
- NewRatio:新生代与老年代的比例。
- SurvivorRatio:Eden区和Survivor区的比例。
- MetaspaceSize:元空间(Metaspace)的初始大小。
- CompressedClassSpaceSize:压缩类空间的大小。
- MaxMetaspaceSize:元空间的最大大小。
- G1HeapRegionSize:使用G1收集器时的堆区域大小。
Heap Usage 部分显示了Java堆的使用情况,包括各个区域的容量、已用空间和空闲空间:
- PS Young Generation:表示Parallel Scavenge GC中的新生代(Parallel Scavenge是一种垃圾收集器)
- Eden Space:伊甸园区域的容量、已用空间和空闲空间。
- From Space:幸存者(Survivor)区中的From区域的容量、已用空间和空闲空间。
- To Space:幸存者(Survivor)区中的To区域的容量、已用空间和空闲空间。
- PS Old Generation:表示Parallel Scavenge GC中的老年代。
- capacity:容量。
- used:已使用的空间。
- free:可用的空闲空间。
- 最后一行 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
这个执行结果是一个对象直方图,列出了不同类的实例数量和占用的内存大小。下面是对每个列的解释:
- num:序号,表示第几行。
- #instances:实例数量,表示内存中存在多少个该类的实例。
- #bytes:内存大小,表示该类实例所占用的总字节数。
- 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和内存。
 而如果生成的堆转储文件非常庞大时,需要使用专门的工具(如 jhat、MAT等)进行解读和分析。
MAT(Memory Analyzer Tool)是一个Java堆分析器,它是一款强大的开源工具,用于分析Java应用程序在运行时产生的内存问题。MAT可以帮助开发人员快速定位和解决内存泄漏、大对象占用过多内存、内存溢出等常见的内存相关问题。
MAT提供了多种功能和特性:
- 内存快照分析:可以加载并分析通过
jmap或者其他工具生成的Java堆转储文件(如hprof格式),以获取详细的内存使用情况。- 强大的查询和筛选功能:支持丰富的查询语言和过滤条件,方便开发人员查找特定类型的对象,快速定位问题所在。
- 可视化对象图:以直观的方式展示Java堆中的对象及其引用关系,帮助开发人员理解对象之间的关联,从而更好地排查内存问题。
- 内存报告和统计:生成详细的内存报告,包括对象数量、内存占用、GC根引用等统计信息,帮助开发人员分析对象的分布和趋势。
- 内存泄漏检测:自动检测可能造成内存泄漏的对象,识别存在潜在泄漏的代码路径,辅助开发人员修复内存问题。
- 快速分析和低内存占用:
MAT具有高效的内存使用和分析性能,即使在处理大型堆转储文件时也能保持较低的内存占用。
🌾 总结
jmap命令是Java开发工具包(JDK)中的一个有用工具,用于生成Java堆转储文件以及查看堆和对象统计信息。通过连接到运行中的Java进程,jmap提供了快速生成内存快照的方式,帮助开发人员检测和调试Java应用程序的内存问题。然而,使用时需要注意权限、资源消耗以及处理生成的大型转储文件的需求。综上所述,jmap是一个强大的工具,适用于各种Java内存分析和调优的场景。
 
 
 
                
![[LeetCode - Python]349. 两个数组的交集(Easy);350. 两个数组的交集 II(Easy)](https://img-blog.csdnimg.cn/9a82739d4f124e6bab7c2e458b200881.png)

















