JVM 命令指北(5)-jmap 命令

1. 功能简介

jmapJDK 自带的工具软件,可用于生成指定 Java 进程的 Heap Dump 文件, 也可以查看堆内对象实例的统计信息、ClassLoader 的信息以及 finalizer 队列中等待被回收的对象的信息。 JDK 自带的工具都有 Java 进程所属用户的概念,需注意如果当前登录用户和进程启动用户不是同一个时,该命令无法获取到正确信息

2. 使用方式

在终端界面使用 man jmap 可以方便地获得 jmap 命令帮助文档,其命令格式如下

命令格式 参数说明
jmap [ option ] pid pid 为 Java 应用程序的进程号
jmap [ option ] executable core executable 为产生core dump的 java可执行程序,core为打印出的core文件
jmap [ option ] [ server-id@] remote-hostname-or-IP remote-hostname-or-ip 是远程 debug 服务器的名称或IP,server-id是唯一id,假如一台主机上有多个远程 debug 服务会需要区分
Options 功能
< no option > 使用不带选项参数的jmap命令将会打印目标虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称
-dump:[live,]format=b,file=< filename > hprof 二进制格式转储 Java 堆到指定 fileName 的文件中。如果指定了live子选项,只有 Active 状态的对象会被转储,会触发 Full GC, gc log 中关键字为 Heap Dump Initiated GC,可以使用jhat(Java堆分析工具)读取生成的 heap dump 文件
-finalizerinfo 打印等待回收的对象信息
-heap 打印堆的简要信息,包括使用的GC算法、堆配置信息和generation wise heap usage
-histo[:live] 打印堆中对象信息,包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果指定了live子选项,则只计算活动的对象,会触发 Full GC,gc log 中的关键字为 Heap Inspection Initiated GC
-clstats Java 8 之后 HotSpot 虚拟机永久代取消,取代 -permstat 的参数选项,可打印元空间的类加载器的统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。另外,包含的字符串数量和大小也会被打印
-F 强制模式,如果指定的 pid 没有响应,建议使用 jmap -dumpjmap -histo 选项,该模式下不支持live子选项
-J< flag > 传递指定参数给运行 jmap 的 JVM

3. 基本示例

3.1 -heap 选项

 jmap -heap 14480

使用以上命令查看 Java 进程 14480 的堆(heap)使用情况,打印如下信息

// 开启了线程本地分配缓冲区(TLAB)
using thread-local object allocation.
// 并行 GC 收集算法,4 个线程 
Parallel GC with 4 thread(s)
// 堆内存区域初始化配置
Heap Configuration:
   // 对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
   MinHeapFreeRatio         = 0
   // 设置JVM堆最大空闲比率(default 70)
   MaxHeapFreeRatio         = 100
   // 对应jvm启动参数-XX:MaxHeapSize= 设置JVM堆的最大大小
   MaxHeapSize              = 134217728 (128.0MB)
   // 对应jvm启动参数-XX:NewSize= 设置JVM堆‘新生代’的默认大小
   NewSize                  = 42991616 (41.0MB)
   // 对应jvm启动参数-XX:MaxNewSize= 设置JVM堆的‘新生代’的最大大小
   MaxNewSize               = 44564480 (42.5MB)
   // 对应jvm启动参数-XX:OldSize= 设置JVM堆的‘老年代’的大小
   OldSize                  = 87031808 (83.0MB)
   // 对应jvm启动参数-XX:NewRatio= 设置‘新生代’和‘老生代’的大小比率
   NewRatio                 = 2
    // 对应jvm启动参数-XX:SurvivorRatio= 设置年轻代中Eden区与Survivor区的大小比值 
   SurvivorRatio            = 8
   // 对应jvm启动参数-XX:MetaspaceSize= , Java 8 之后类相关信息存放在元空间(不属于堆内存),此为元空间初始化大小
   MetaspaceSize            = 21807104 (20.796875MB)
   // 类指针压缩空间大小, 默认为1G。UseCompressedClassPointer 这个选项打开后,class信息中的指针也用 32bit
   // 的 Compressed版本,而这些指针指向的空间被称作“Compressed Class Space”。如果java程序引用了太多的包,
   // 有可能会造成这个空间不够用,于是会看到java.lang.OutOfMemoryError: Compressed class space 这时
   // 一般调大CompreseedClassSpaceSize 就可以了,-XX:CompressedClassSpaceSize=
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   // 对应jvm启动参数-XX:MaxMetaspaceSize= 设置元空间最大大小
   MaxMetaspaceSize         = 17592186044415 MB
   // G1 收集器单个 region 的大小
   G1HeapRegionSize         = 0 (0.0MB)


Heap Usage:
// 年轻代内存使用情况
PS Young Generation
Eden Space:
   capacity = 26214400 (25.0MB)
   used     = 16168040 (15.419044494628906MB)
   free     = 10046360 (9.580955505371094MB)
   61.676177978515625% used
From Space:
   capacity = 524288 (0.5MB)
   used     = 266000 (0.2536773681640625MB)
   free     = 258288 (0.2463226318359375MB)
   50.7354736328125% used
To Space:
   capacity = 524288 (0.5MB)
   used     = 0 (0.0MB)
   free     = 524288 (0.5MB)
   0.0% used
// 年老代内存使用情况
PS Old Generation
   capacity = 73400320 (70.0MB)
   used     = 73146256 (69.75770568847656MB)
   free     = 254064 (0.2422943115234375MB)
   99.65386526925224% used
// 字符串常量池中的字符串信息
31347 interned Strings occupying 3713392 bytes.

3.2 -histo 选项

// 将对内存中类相关信息输入到目标文件
 jmap -histo 17134 > heap.log
 // 查看该文件到前10行
 head heap.log

jmap -histo 命令打印堆内存中的对象数量及其所占内存的大小,通常这个列表会很大,终端界面不可能完全显示,所以最好将其输出到一个文件中,再查看这个文件即可。注意 jmap -histo:live 这个命令执行,JVM 会先触发 Full GC,然后再统计信息

 num     #instances         #bytes  class name
 编号      实例数量          占用内存  类的名称
 ----------------------------------------------
   1:         90382        8994744  [C
   2:         90151        2163624  java.lang.String
   3:         63510        2032320  java.util.concurrent.ConcurrentHashMap$Node
   4:         13058        1451536  java.lang.Class
   5:         15017        1321496  java.lang.reflect.Method
   6:          7809        1158504  [B
   7:         19242        1153512  [Ljava.lang.Object;
  • 输出中 class name 非自定义类对照表
    非自定义类 数据类型
    B byte
    C char
    S short
    I int
    J long
    F float
    D double
    Z boolean
    [ 一维数组引用
    L 类实例引用

3.3 -dump 选项

 jmap -dump:live,format=b,file=dump 17134

这个命令执行,JVM会将整个 heap 的信息 dump 输出到指定文件,如果 heap 比较大会导致这个过程比较耗时,并且执行的过程中为了保证 dump 的信息是可靠的,JVM 会暂停程序运行。dump 文件生成后,可运行命令jhat -port 10086 dump, 在浏览器中访问 http://localhost:10086/即可查看详细信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章