Java 工具集教程

jmap.exe Java内存图

jmap.exe 是 JDK 中的一个命令行工具,全称为 JVM Memory Map,主要用于查看 Java 堆内存的使用状况。

jmap 可以生成堆的转储快照(dump文件),也可以查看堆内存中的对象实例数量、内存大小等信息。

jmap 生成的 dump 文件可以配合 jhat 工具进行分析,jhat 会启动一个 web 服务,用户可以通过浏览器查看和分析 dump 文件。

jmap 提供了多种生成堆转储文件的方式,包括在 JVM 运行时获取 dump 文件,以及在 JVM 启动时指定参数,当发生 OutOfMemoryError 时自动执行堆转储。

命令语法

连接正在运行的进程:

jmap [option] <pid>

连接到核心文件:

jmap [option] <executable <core>

连接远程调试服务器:

jmap [option] [server_id@]<remote server IP or hostname>

命令选项

jmap 支持如下选项:

  • <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 一起使用,可在 <pid> 没有响应时强制转储堆或直方图。该模式下不支持 "live" 子选项。

  • -h | -help 用于打印帮助信息

  • -J<flag>  直接将 <flag> 传递给运行时系统。

命令示例

(1)查看进程的内存映像信息,如下:

D:\share_dir\ShareDoc> jmap 21108
Attaching to process ID 21108, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.45-b02
0x0000000051ca0000      44K     D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\sunmscapi.dll
0x0000000051cb0000      144K    D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\sunec.dll
0x0000000051ce0000      52K     D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\management.dll
0x0000000051cf0000      140K    D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\instrument.dll
0x0000000051d20000      68K     D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\nio.dll
0x0000000051d40000      104K    D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\net.dll
0x0000000051d60000      88K     D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\zip.dll
0x0000000051d80000      164K    D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\java.dll
0x0000000051db0000      60K     D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\verify.dll
0x0000000051dc0000      8716K   D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\server\jvm.dll
0x0000000052650000      840K    D:\ProgramFilesFree\Java\jdk1.8.0_45\jre\bin\msvcr100.dll
0x00007ff7b13c0000      220K    D:\ProgramFilesFree\Java\jdk1.8.0_45\bin\java.exe
....

上面示例中,打印 Java 进程ID 为 21108 虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称。

(2)显示 Java 堆的详细信息,如下:

D:\share_dir\ShareDoc> jmap -heap 21108
Attaching to process ID 21108, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.45-b02

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

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 4227858432 (4032.0MB)
   NewSize                  = 88080384 (84.0MB)
   MaxNewSize               = 1409286144 (1344.0MB)
   OldSize                  = 176160768 (168.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 = 138936320 (132.5MB)
   used     = 58500320 (55.790252685546875MB)
   free     = 80436000 (76.70974731445312MB)
   42.1058510834316% used
From Space:
   capacity = 7864320 (7.5MB)
   used     = 5242880 (5.0MB)
   free     = 2621440 (2.5MB)
   66.66666666666667% used
To Space:
   capacity = 12058624 (11.5MB)
   used     = 0 (0.0MB)
   free     = 12058624 (11.5MB)
   0.0% used
PS Old Generation
   capacity = 146276352 (139.5MB)
   used     = 25092136 (23.929725646972656MB)
   free     = 121184216 (115.57027435302734MB)
   17.15392519496248% used

19171 interned Strings occupying 1776256 bytes.

上面命令将显示 Java 进程ID 为 21108 虚拟机的信息,包括使用的垃圾回收算法、堆配置信息和各内存区域内存使用信息在内的 Java 堆的详细信息。

(3)显示堆中对象的统计信息,如下:

D:\share_dir\ShareDoc> jmap -histo:live 21108 > tmp.txt
 num     #instances         #bytes  class name
----------------------------------------------
   1:         40968        4257264  [C
   2:         11868        1044384  java.lang.reflect.Method
   3:         40478         971472  java.lang.String
   4:          8132         899808  java.lang.Class
   5:         27347         875104  java.util.concurrent.ConcurrentHashMap$Node
   6:          4404         567288  [B
   7:          8457         429488  [Ljava.lang.Object;
   8:          9451         378040  java.util.LinkedHashMap$Entry
   9:          4067         329616  [Ljava.util.HashMap$Node;
  10:          6008         288384  org.aspectj.weaver.reflect.ShadowMatchImpl
  11:          4694         262864  java.util.LinkedHashMap
  12:          7617         243744  java.util.HashMap$Node
  13:           116         233536  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  14:          3877         212368  [I
...
3264:             1             16  sun.util.locale.provider.SPILocaleProviderAdapter
3265:             1             16  sun.util.locale.provider.TimeZoneNameUtility$TimeZoneNameGetter
3266:             1             16  sun.util.resources.LocaleData
3267:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total        304943       14876288

上面命令将显示堆中对象的统计信息,包括每个Java类、对象数量、内存大小(单位:字节)和完全限定的类名。指定了live子选项,因此只计算活动的对象。

(4)打印类加载器信息,如下:

D:\share_dir\ShareDoc> jmap -clstats 21108
Attaching to process ID 21108, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.45-b02
finding class loader instances ..done.
computing per loader stat ..done.
please wait.. computing liveness.liveness analysis may be inaccurate ...
class_loader    classes bytes   parent_loader   alive?  type

<bootstrap>     2442    4306147   null          live    <internal>
0x00000006c4b166b0      1       880       null          dead    sun/reflect/DelegatingClassLoader@0x00000007c0009df8
0x000000076d218120      3       6022    0x00000006c40142e8      dead    javax/management/remote/rmi/RMIConnectionImpl$CombinedClassLoader@0x00000007c02daa38
0x00000006c4dd00d8      1       1471      null          dead    sun/reflect/DelegatingClassLoader@0x00000007c0009df8
0x000000076cf698f0      0       0         null          dead    com/sun/jmx/remote/util/OrderClassLoaders@0x00000007c053e290
0x000000076ec04ac8      3       6022    0x00000006c40142e8      dead    javax/management/remote/rmi/RMIConnectionImpl$CombinedClassLoader@0x00000007c02daa38
0x00000006c4b164b8      1       880       null          dead    sun/reflect/DelegatingClassLoader@0x00000007c0009df8
...
0x000000076e956d68      0       0       0x000000076e956930      dead    javax/management/remote/rmi/RMIConnectionImpl$CombinedClassLoader$ClassLoaderWrapper@0x00000007c02dad50
0x00000006c4de9d20      1       1471      null          dead    sun/reflect/DelegatingClassLoader@0x00000007c0009df8

total = 277     8342    14807542            N/A         alive=1, dead=276           N/A

上面命令将打印 Java 堆内存的方法区的类加载器的智能统计信息,包括类加载器的名称、活跃度、地址、父类加载器以及加载的类的数量和大小。

(5)生成堆转储快照 dump 文件,如下:

D:\share_dir\ShareDoc> jmap -dump:format=b,file=heapdump.hprof 21108
Dumping heap to D:\share_dir\ShareDoc\heapdump.hprof ...
Heap dump file created

上面命令将以二进制格式将 Java 堆转储到名为 heapdump.hprof 的文件中,可以使用 jhat 或其他堆分析工具来分析这个文件。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号