返回
Featured image of post JVM调优(二)

JVM调优(二)

JVM调优 - 分析工具

简述

Java 自带很多工具能够辅助我们完成对 Java 应用的性能指标分析。 本文将介绍下列 5 种命令行工具。

jps

JPS 全程 Java Virtual Machine Process Status Tool,是 Java 提供的一个显示当前所有 Java 进程 PID 的命令,适合简单查看当前 Java 进程的信息。

运行格式

jps [ options ] [ hostid ]

参数介绍

参数 描述
-q 仅生成本地 VM 标识符列表,不打印 main 方法的类名、JAR 文件名和参数的输出。
-m 输出传递给 main 方法的参数。对于嵌入式 JVM,输出可能为 null
-l 输出应用程序主类的完整包名或应用程序 JAR 文件的完整路径名。
-v 输出 JVM 的参数。
-V 通过标志文件(.hotspotrc 文件或 -XX:Flags=‘filename’ 参数指定的文件)输出传递给 JVM 的参数。
-Joption 将参数传递给 JPS 调用的 Java 启动器。例如,-J-Xms48m 将启动内存设置为 48Mb。 -J 将选项传递给执行应用程序的底层 VM 是一种一般规范。

使用

$ jps
30444 rest-service-0.0.1-SNAPSHOT.jar
9460 Jps

$ jps -q
30444
9460

$ jps -m
30236 Jps -m
30444 rest-service-0.0.1-SNAPSHOT.jar -XX:+UseG1GC

$ jps -l
31812 sun.tools.jps.Jps
30444 .\rest-service-0.0.1-SNAPSHOT.jar

$ jps -v
29260 Jps -Denv.class.path=.;C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\\lib\dt.jar;C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\\lib\tools.jar; -Dapplication.home=C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot -Xms8m
30444 rest-service-0.0.1-SNAPSHOT.jar

$ jps -J-Xms48m -v
16060 Jps -Denv.class.path=.;C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\\lib\dt.jar;C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\\lib\tools.jar; -Dapplication.home=C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot -Xms8m -Xms48m
30444 rest-service-0.0.1-SNAPSHOT.jar

jstat

jstat 工具能够显示 HotSpot Java 虚拟机 (JVM) 的性能统计信息。目标 JVM 由其虚拟机标识符或下面描述的 vmid 参数来确定。

运行格式

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

输出参数

参数 描述
-help 显示帮助信息
-options 显示统计参数列表。
参数 显示内容
-class 类加载器行为统计信息。
-compiler HotSpot JIT 编译器行为统计信息。
-gc GC 堆的行为统计。
-gccapacity Heap 中对象年龄代的容量及其相应空间的统计。
-gccause 垃圾收集统计信息摘要(与 -gcutil 相同),以及上次和当前(如果适用)垃圾收集事件的原因。
-gcnew 新生代行为统计。
-gcnewcapacity 新生代的大小及其对应的空间的统计信息。
-gcold 老年代和永久代的行为统计。(JDK 1.7); 老年代和元空间的行为统计。(JDK 1.8);
-gcoldcapacity 老年代容量的统计。
-gcmetacapacity 元空间容量的统计。(JDK 1.8)
-gcpermcapacity 永久代容量的统计。(JDK 1.7)
-gcutil 垃圾收集统计摘要。
-printcompilation HotSpot 编译方法统计。

使用

-class

Class loader 统计信息

$ jstat -class 30444
Loaded  Bytes  Unloaded  Bytes     Time
  5544 10174.8        0     0.0       1.73
参数名称 描述
Loaded 加载的类的数量。
Bytes 加载的类大小,单位:KB
Unloaded 卸载的类的数量。
Bytes 卸载的类大小,单位:KB
Time 执行类加载和卸载操作所花费的时间。

-compiler

Java HotSpot VM Just-in-Time 编译器统计信息

$ jstat -compiler 30444
Compiled Failed Invalid   Time   FailedType FailedMethod
    3084      1       0     3.29          1 java/lang/StringCoding encode
参数名称 描述
Compiled 执行的编译数。
Failed 编译任务失败数。
Invalid 失效的编译数。
Time 执行编译任务所花费的时间。
FailedType 上次失败编译的编译类型。
FailedMethod 上次编译失败的类名和方法。

-gc

GC 的统计信息。

$ jstat -gc 30444
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
3072.0 10752.0 3008.0  0.0   96256.0  56913.5   104960.0    7314.0   27440.0 25574.4 3632.0 3186.9      4    0.020   1      0.018    0.038
参数名称 描述
S0C 当前 Survivor 0 的容量 (KB)。
S1C 当前 Survivor 1 的容量 (KB)。
S0U 当前 Survivor 0 的使用大小 (KB)。
S1U 当前 Survivor 1 的使用大小 (KB)。
EC 当前 Eden 区的容量 (KB)。
EU 当前 Eden 区的使用大小 (KB)。
OC 当前 Old 区的容量 (KB)。
OU 当前 Old 区的使用大小 (KB)。
PC 永久代的容量 (KB)。(JDK 1.7)
PU 永久代的使用大小 (KB)。(JDK 1.7)
MC 元空间的容量 (KB)。(JDK 1.8)
MU 元空间的使用大小 (KB)。(JDK 1.8)
CCSC 类压缩空间的容量 (KB)。(JDK 1.8)
CCSU 类压缩空间的使用大小 (KB)。(JDK 1.8)
YGC Young GC 触发次数。
YGCT Young GC 运行时间。
FGC Full GC 触发次数。
FGCT Full GC 运行时间。
GCT GC 时间。

-gccapacity

内存池生成和空间容量。

$ jstat -gccapacity 30444
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC
 86528.0 1379328.0 143872.0 3072.0 10752.0  96256.0   173568.0  2759680.0   104960.0   104960.0      0.0 1073152.0  27440.0      0.0 1048576.0   3632.0      4     1
参数名称 描述
NGCMN 新生代最小容量 (KB)。
NGCMX 新生代最大容量 (KB)。
NGC 当前新生代容量 (KB)。
S0C 当前 Survivor 0 的容量 (KB)。
S1C 当前 Survivor 1 的容量 (KB)。
EC 当前 Eden 区的容量 (KB)。
OGCMN 老年代最小容量 (KB)。
OGCMX 老年代最大容量 (KB)。
OGC 当前老年代容量 (KB)。
OC 当前 Old 空间容量 (KB)。
PGCMN 最小永久代容量 (KB)。(JDK 1.7)
PGCMX 最大永久代容量 (KB)。(JDK 1.7)
PGC 当前永久代容量 (KB)。(JDK 1.7)
PC 当前 Permanent 空间容量 (KB)。(JDK 1.7)
MCMN 最小元空间容量 (KB)。 (JDK 1.8)
MCMX 最大元空间容量 (KB)。 (JDK 1.8)
MC 当前元空间大小 (KB)。 (JDK 1.8)
CCSMN 最小类压缩空间容量 (KB)。 (JDK 1.8)
CCSMX 最大类压缩空间容量 (KB)。 (JDK 1.8)
CCSC 当前类压缩空间容量 (KB)。 (JDK 1.8)
YGC Young GC 触发次数。
FGC Full GC 触发次数。

-gccause

此选项显示与 -gcutil 选项相同的垃圾收集统计摘要信息,但包括上次垃圾收集事件和当前垃圾收集事件的原因(如果适用)。除了 -gcutil 列出的之外,此选项还添加了以下列。

$ jstat -gccause 30444
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC

 97.92   0.00  59.13   6.97  93.20  87.74      4    0.020     1    0.018    0.038 Allocation Failure   No GC

参数名称 描述
LGCC 上次垃圾回收的原因。
GCC 当前垃圾回收的原因。

-gcnew

新生代统计信息。

$ jstat -gcnew 30444
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
3072.0 10752.0 3008.0    0.0  7  15 10752.0  96256.0  56913.5      4    0.020
参数名称 描述
S0C 当前 Survivor 0 的容量 (KB)。
S1C 当前 Survivor 1 的容量 (KB)。
S0U 当前 Survivor 0 的使用大小 (KB)。
S1U 当前 Survivor 0 的使用大小 (KB)。
TT 对象在新生代存活的次数。
MTT 对象在新生代存活的最大次数。
DSS 期望的 Survivor 区大小 (KB)。
EC Eden 区的容量 (KB)。
EU Eden 区的使用大小 (KB)。
YGC Young GC 触发次数。
YGCT Young GC 运行时间。

-gcnewcapacity

新生代空间大小统计。

$ jstat -gcnewcapacity 30444
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC
   86528.0  1379328.0   143872.0 459776.0   3072.0 459776.0  10752.0  1378304.0    96256.0     4     1
参数名称 描述
NGCMN 新生代最小容量 (KB)。
NGCMX 新生代最小容量 (KB)。
NGC 当前新生代容量 (KB)。
S0CMX 最大 Survivor 0 的容量 (KB)。
S0C 当前 Survivor 0 的容量 (KB)。
S1CMX 最大 Survivor 1 的容量 (KB)。
S1C 当前 Survivor 1 的容量 (KB)。
ECMX 最大 Eden 区的容量 (KB)。
EC 当前 Eden 区的容量 (KB)。
YGC Young GC 触发次数。
FGC Full GC 触发次数。

-gcold

  • 老一代和永久代统计。(JDK 1.7)
  • 老年代和元空间行为统计。(JDK 1.8)
$ jstat -gcold 30444
   MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT
 27440.0  25574.4   3632.0   3186.9    104960.0      7314.0      4     1    0.018    0.038
参数名称 描述
PC 永久代的容量 (KB)。(JDK 1.7)
PU 永久代的使用大小 (KB)。(JDK 1.7)
MC 元空间的容量 (KB)。(JDK 1.8)
MU 元空间的使用大小 (KB)。(JDK 1.8)
CCSC 类压缩空间的容量 (KB)。(JDK 1.8)
CCSU 类压缩空间的使用大小 (KB)。(JDK 1.8)
OC 当前 Old 区的容量 (KB)。
OU 当前 Old 区的使用大小 (KB)。
YGC Young GC 触发次数。
FGC Full GC 触发次数。
FGCT Full GC 运行时间。
GCT GC 时间。

-gcoldcapacity

老年代大小统计信息。

$ jstat -gcoldcapacity 30444
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT
   173568.0   2759680.0    104960.0    104960.0     4     1    0.018    0.038
参数名称 描述
OGCMN 老年代最小容量 (KB)。
OGCMX 老年代最大容量 (KB)。
OGC 当前老年代容量 (KB)。
OC 当前 Old 区的容量 (KB)。
YGC Young GC 触发次数。
FGC Full GC 触发次数。
FGCT Full GC 运行时间。
GCT GC 时间。

-gcpermcapacity (JDK 1.7 Only)

永久代大小统计信息

参数名称 描述
PGCMN 最小永久代容量 (KB)。
PGCMX 最大永久代容量 (KB)。
PGC 当前永久代容量 (KB)。
PC 当前 Permanent 空间容量 (KB)。
YGC Young GC 触发次数。
FGC Full GC 触发次数。
FGCT Full GC 运行时间。
GCT GC 时间。

-gcmetacapacity (JDK 1.8 Only)

元空间大小统计信息。

$ jstat -gcmetacapacity 30444
   MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT
       0.0  1073152.0    27440.0        0.0  1048576.0     3632.0     4     1    0.018    0.038
参数名称 描述
MCMN 最小元空间容量 (KB)。
MCMX 最大元空间容量 (KB)。
MC 当前元空间大小 (KB)。
CCSMN 最小类压缩空间容量 (KB)。
CCSMX 最大类压缩空间容量 (KB)。
YGC Young GC 触发次数。
FGC Full GC 触发次数。
FGCT Full GC 运行时间。
GCT GC 时间。

-gcutil

垃圾收集统计概要。

$ jstat -gcutil 30444
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
 97.92   0.00  59.13   6.97  93.20  87.74      4    0.020     1    0.018    0.038
参数名称 描述
S0 Survivor 0 空间利用率。单位:%
S1 Survivor 1 空间利用率。单位:%
E Eden 区空间利用率。单位:%
O Old 区空间利用率。单位:%
P Permanent 区空间利用率。单位:%。(JDK 1.7)
M Metaspace 空间利用率。单位:%。(JDK 1.8)
CCS 类压缩空间利用率。单位:%。(JDK 1.8)
YGC Young GC 触发次数。
YGCT Young GC 运行时间。
FGC Full GC 触发次数。
FGCT Full GC 运行时间。
GCT GC 时间。

-printcompilation

Java HotSpot VM 编译器方法统计信息。

$ jstat -printcompilation 30444
Compiled  Size  Type Method
    3107    172    1 java/util/concurrent/locks/AbstractQueuedSynchronizer release
参数名称 描述
Compiled 最近编译的方法执行的编译任务数。
Size 最近编译的方法的字节码的字节数。
Type 最近编译的方法的编译类型。
Method 最近编译的方法的类名和方法名。类名使用斜线 (/) 而不是点 (.) 作为名称空间分隔符。方法名称是指定类中的方法。这两个字段的格式与 HotSpot -XX:+PrintCompilation 选项一致。

jstack

jstackJava 虚拟机自带的一种堆栈跟踪工具。jstack 为给定的 Java 进程或核心文件或远程调试服务器打印 Java 线程的 Java 堆栈跟踪。对于每个 Java 框架,将打印完整的类名、方法名、bci(字节码索引)和行号(如果有)。使用 -m 选项,jstack 命令使用程序计数器 (PC) 打印所有线程的 Java 和本机帧。对于每个原生帧,打印最接近 PC 的原生符号(如果可用)。当指定的进程在 64Java 虚拟机上运行时,您可能需要指定 -J-d64 选项,例如:jstack -J-d64 -m pid

格式

jstack [ options ] pid

jstack [ options ] executable core

jstack [ options ] [ server-id@ ] remote-hostname-or-IP
关键字 描述
options 命令行参数
pid 打印堆栈跟踪的进程 ID。该进程必须是 Java 进程。
executable 从中生成核心转储的 Java 可执行文件。
core 要打印堆栈跟踪的核心文件。
remote-hostname-or-IP 远程调试服务器主机名或 IP 地址。
server-id 当多个调试服务器在同一远程主机上运行时使用的可选唯一 ID

参数

参数名称 描述
-F jstack [-l] pid 没有响应时强制进行堆栈转储。
-l 大量列出信息。打印有关锁的附加信息,例如拥有的java.util.concurrent 可拥有的同步器列表。
-m 打印具有 JavaNative C/C++ 帧的混合模式堆栈跟踪。
-h 打印帮助消息。
-help 打印帮助消息。

使用

$ jstack 30444
2021-08-19 16:05:29
Full thread dump OpenJDK 64-Bit Server VM (25.282-b08 mixed mode):

"DestroyJavaVM" #31 prio=5 os_prio=0 tid=0x00000187de146800 nid=0x78e8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"http-nio-8080-Acceptor" #30 daemon prio=5 os_prio=0 tid=0x00000187de145800 nid=0x4790 runnable [0x0000005d8d2ff000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:421)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:249)
        - locked <0x000000076ed7ec98> (a java.lang.Object)
        at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:551)
        at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:80)
        at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:106)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-ClientPoller" #29 daemon prio=5 os_prio=0 tid=0x00000187de145000 nid=0x5848 runnable [0x0000005d8d1fe000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:314)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:293)
        at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:174)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x000000076eef6158> (a sun.nio.ch.Util$3)
        - locked <0x000000076eef6148> (a java.util.Collections$UnmodifiableSet)
        - locked <0x000000076eef5ff8> (a sun.nio.ch.WindowsSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:793)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-10" #28 daemon prio=5 os_prio=0 tid=0x00000187de143000 nid=0x5584 waiting on condition [0x0000005d8d0fe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-9" #27 daemon prio=5 os_prio=0 tid=0x00000187de142800 nid=0x7bb8 waiting on condition [0x0000005d8cfff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-8" #26 daemon prio=5 os_prio=0 tid=0x00000187de148800 nid=0x83b0 waiting on condition [0x0000005d8ceff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-7" #25 daemon prio=5 os_prio=0 tid=0x00000187de149800 nid=0x8190 waiting on condition [0x0000005d8cdfe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-6" #24 daemon prio=5 os_prio=0 tid=0x00000187de144000 nid=0x3574 waiting on condition [0x0000005d8ccff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-5" #23 daemon prio=5 os_prio=0 tid=0x00000187de037000 nid=0x7b64 waiting on condition [0x0000005d8cbff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-4" #22 daemon prio=5 os_prio=0 tid=0x00000187dcb9e000 nid=0x2a50 waiting on condition [0x0000005d8cafe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-3" #21 daemon prio=5 os_prio=0 tid=0x00000187dcb9d800 nid=0x785c waiting on condition [0x0000005d8c9fe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-2" #20 daemon prio=5 os_prio=0 tid=0x00000187ddede800 nid=0x44c0 waiting on condition [0x0000005d8c8fe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-1" #19 daemon prio=5 os_prio=0 tid=0x00000187dd29d800 nid=0x4444 waiting on condition [0x0000005d8c7fe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ee9e510> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-BlockPoller" #18 daemon prio=5 os_prio=0 tid=0x00000187dea3b800 nid=0x1d70 runnable [0x0000005d8c6fe000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:314)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:293)
        at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:174)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x000000076ed81670> (a sun.nio.ch.Util$3)
        - locked <0x000000076ed815e8> (a java.util.Collections$UnmodifiableSet)
        - locked <0x000000076ed811e8> (a sun.nio.ch.WindowsSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:313)

"container-0" #17 prio=5 os_prio=0 tid=0x00000187de6c4800 nid=0x5488 waiting on condition [0x0000005d8c5ff000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at org.apache.catalina.core.StandardServer.await(StandardServer.java:570)
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer$1.run(TomcatWebServer.java:197)

"Catalina-utility-2" #16 prio=1 os_prio=-2 tid=0x00000187dea67000 nid=0x66f4 waiting on condition [0x0000005d8c4fe000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007746f4b70> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"Catalina-utility-1" #15 prio=1 os_prio=-2 tid=0x00000187de4b8800 nid=0x3bf4 waiting on condition [0x0000005d8c3fe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007746f4b70> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x00000187dc61f000 nid=0x2b7c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread3" #9 daemon prio=9 os_prio=2 tid=0x00000187da84a800 nid=0x5184 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x00000187da841800 nid=0x42f0 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x00000187da840800 nid=0x5c34 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x00000187da844800 nid=0x4184 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000187da838000 nid=0x2638 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x00000187da7e5000 nid=0x5218 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000187da7b0800 nid=0x7a3c in Object.wait() [0x0000005d8b9ff000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000006c3630078> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
        - locked <0x00000006c3630078> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000187da7a8800 nid=0x685c in Object.wait() [0x0000005d8b8ff000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000006c36099b0> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x00000006c36099b0> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=2 tid=0x00000187da77d800 nid=0x2fd4 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000187bf85c800 nid=0x715c runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000187bf85e000 nid=0x558c runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000187bf85f800 nid=0x2b90 runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00000187bf861800 nid=0x83f4 runnable

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00000187bf863800 nid=0x3198 runnable

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00000187bf866000 nid=0x413c runnable

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00000187bf869000 nid=0x607c runnable

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00000187bf86b800 nid=0x49cc runnable

"VM Periodic Task Thread" os_prio=2 tid=0x00000187dc631000 nid=0x5018 waiting on condition

JNI global references: 1315

jmap

打印进程、核心文件或远程调试服务器的共享对象内存映射或堆内存详细信息。 jmap 命令打印指定进程、核心文件或远程调试服务器的共享对象内存映射或堆内存详细信息。如果指定的进程在 64Java 虚拟机 (JVM) 上运行,那么您可能需要指定 -J-d64 选项,例如:jmap -J-d64 -heap pid

格式

jmap [ options ] pid

jmap [ options ] executable core

jmap [ options ] [ pid ] server-id@ ] remote-hostname-or-IP
关键字 描述
options 命令行参数
pid 要为其打印内存映射的进程 ID。该进程必须是 Java 进程。
executable 从中生成核心转储的 Java 可执行文件。
core 要为其打印内存映射的核心文件。
remote-hostname-or-IP 远程调试服务器主机名或 IP 地址。
server-id 当多个调试服务器在同一远程主机上运行时使用的可选唯一 ID

参数

参数名称 描述
<no option> 当不使用任何选项时,jmap 命令打印共享对象映射。对于目标JVM 中加载的每个共享对象,都会打印出该共享对象文件的起始地址、映射大小和完整路径。。
-dump:[live,] format=b, file=filename hprof 二进制格式的 Java 堆转储到指定文件。 live 是可选子选项,当指定时,只会转储堆中的活动对象,且会触发一次 Full GC。要浏览堆转储,您可以使用 jhat 命令读取生成的 Dump 文件。
-finalizerinfo 打印有关等待完成的对象的信息。
-heap 打印使用的垃圾收集的堆摘要、头配置和按代计算的堆使用情况。此外,还打印了已存入常量池字符串(Interned String)的数量和大小。
-histo[:live] 打印堆的直方图。对于每个 Java 类,将打印对象数、内存大小(以Byte 为单位)和完整的类名。JVM 内部类以星号 (*) 前缀打印。如果指定了 live 子选项,则只计算活动对象,且会触发 Full GC
-clstats 打印 Java 堆的类加载器的统计信息。对于每个类加载器,它的名称、它的活跃程度、地址、父类加载器以及它已加载的类的数量和大小都被打印出来。
-F 强制执行。当 pid 没有响应时,将此选项与 jmap -dumpjmap -histo 选项一起使用。此模式不支持 live 子选项。
-h Prints a help message.
-help Prints a help message.
-Jflag JVM参数传递给运行 jmap 命令的 Java 虚拟机。

使用

$ jmap 30444
Attaching to process ID 30444, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.282-b08
0x0000000067ec0000      8616K   C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\jre\bin\server\jvm.dll
0x0000000068c90000      664K    C:\windows\System32\SYSFER.DLL
0x00007ff7f0680000      232K    C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\bin\java.exe
0x00007ff88ce30000      956K    C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\jre\bin\msvcr120.dll
0x00007ff88df40000      664K    C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\jre\bin\msvcp120.dll
0x00007ff8bddc0000      72K     C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\jre\bin\nio.dll
0x00007ff8bde40000      104K    C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\jre\bin\net.dll
0x00007ff8c86d0000      88K     C:\Program Files\AdoptOpenJDK\jdk-8.0.282.8-hotspot\jre\bin\zip.dll
...

打印堆信息

$ jmap -heap 30444
Attaching to process ID 30444, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.282-b08

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

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 4238344192 (4042.0MB)
   NewSize                  = 88604672 (84.5MB)
   MaxNewSize               = 1412431872 (1347.0MB)
   OldSize                  = 177733632 (169.5MB)
   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 = 96468992 (92.0MB)
   used     = 964752 (0.9200592041015625MB)
   free     = 95504240 (91.07994079589844MB)
   1.0000643522843071% used
From Space:
   capacity = 5767168 (5.5MB)
   used     = 0 (0.0MB)
   free     = 5767168 (5.5MB)
   0.0% used
To Space:
   capacity = 8912896 (8.5MB)
   used     = 0 (0.0MB)
   free     = 8912896 (8.5MB)
   0.0% used
PS Old Generation
   capacity = 152567808 (145.5MB)
   used     = 10801024 (10.3006591796875MB)
   free     = 141766784 (135.1993408203125MB)
   7.079490845146048% used

12198 interned Strings occupying 1055840 bytes.

打印直方图

$ jmap -histo 30444

 num     #instances         #bytes  class name
----------------------------------------------
   1:        174537       32059552  [C
   2:         18029       10376192  [B
   3:         12024        5422296  [I
   4:        120292        2887008  java.lang.String
   5:         23155        1576096  [Ljava.lang.Object;
   6:         15764        1008896  java.net.URL
   7:          9748         857824  java.lang.reflect.Method
   8:         34905         721848  [Ljava.lang.Class;
   9:          5977         660736  java.lang.Class
  10:         19036         609152  java.util.concurrent.ConcurrentHashMap$Node
  11:          6649         532944  [Ljava.util.WeakHashMap$Entry;
  12:          6217         490744  [S
  13:          6596         422144  org.springframework.boot.loader.jar.JarFileWrapper
  14:         10008         400320  java.lang.ref.Finalizer
  15:         12209         390688  org.springframework.boot.loader.jar.StringSequence
  16:          4053         361672  [Ljava.util.HashMap$Node;
  17:          8640         345600  java.util.LinkedHashMap$Entry
  18:         10670         341440  java.util.ArrayList$Itr
  19:         10071         322272  java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
  20:          6645         318960  java.util.WeakHashMap
  21:          9621         307872  java.util.HashMap$Node
  22:         12209         293016  org.springframework.boot.loader.jar.JarURLConnection$JarEntryName
  23:          4851         271656  jdk.internal.org.objectweb.asm.Item
  24:           133         258512  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  25:          7366         235712  java.lang.ref.ReferenceQueue
  26:          6632         212224  java.util.zip.ZipCoder
  27:          3646         204176  java.util.LinkedHashMap
  28:          2516         201280  org.springframework.boot.loader.jar.JarURLConnection
  29:          3454         193424  java.util.concurrent.ConcurrentHashMap$KeyIterator
  30:         11965         191440  java.lang.Object
  31:          6765         162360  java.util.ArrayDeque
  32:          3341         160368  java.util.zip.Inflater
  33:           168         158400  [Ljdk.internal.org.objectweb.asm.Item;
  34:          3588         143520  java.util.HashMap$KeyIterator
  35:          3614         137896  [Ljava.lang.reflect.Method;
  36:          1980         132072  [Ljava.lang.String;
  37:          1763         126936  java.lang.reflect.Field
  38:          1052         126240  org.springframework.boot.loader.jar.JarEntry
  39:          1556         124480  java.lang.reflect.Constructor
  40:          7368         117888  java.lang.ref.ReferenceQueue$Lock
  41:          4855         116520  java.lang.StringBuilder
  42:          2278         109344  org.springframework.util.ConcurrentReferenceHashMap$SoftEntryReference
  43:          2229         106992  java.util.HashMap
  44:          4451         106824  java.util.ArrayList
  45:          3169         101408  java.util.LinkedHashMap$LinkedKeyIterator
  46:          1644          92064  java.lang.invoke.MemberName
  47:          2297          91880  java.util.TreeMap$Entry
  48:          1914          91872  org.springframework.core.ResolvableType
  49:          3634          87216  java.util.Collections$UnmodifiableCollection$1
  50:          2153          86120  java.lang.invoke.MethodType
...
Total        767708       68849112

打印直方图 - 存活对象

$ jmap -histo:live 30444

 num     #instances         #bytes  class name
----------------------------------------------
   1:         29265        2933672  [C
   2:         28974         695376  java.lang.String
   3:          5977         660736  java.lang.Class
   4:         17063         546016  java.util.concurrent.ConcurrentHashMap$Node
   5:          6121         538648  java.lang.reflect.Method
   6:          7804         477144  [Ljava.lang.Object;
   7:          3686         366600  [I
   8:          2560         321960  [B
   9:          6117         244680  java.util.LinkedHashMap$Entry
  10:          2719         235344  [Ljava.util.HashMap$Node;
  11:          2605         209424  [Ljava.util.WeakHashMap$Entry;
  12:          6069         194208  java.util.HashMap$Node
  13:         11619         185904  java.lang.Object
  14:           101         181904  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  15:          7568         170520  [Ljava.lang.Class;
  16:          2553         163392  org.springframework.boot.loader.jar.JarFileWrapper
  17:          2759         154504  java.util.LinkedHashMap
  18:          3596         143840  java.lang.ref.Finalizer
  19:          2602         124896  java.util.WeakHashMap
  20:          3131         100192  java.lang.ref.ReferenceQueue
  21:          2589          82848  java.util.zip.ZipCoder
  22:          1002          80160  java.lang.reflect.Constructor
  23:          1058          76176  java.lang.reflect.Field
  24:          1308          73248  java.lang.invoke.MemberName
  25:          2589          62136  java.util.ArrayDeque
  26:          1261          60528  java.util.HashMap
  27:           482          57840  org.springframework.boot.loader.jar.JarEntry
  28:           941          52696  java.lang.Class$ReflectionData
  29:          1254          50160  java.lang.ref.SoftReference
  30:          3133          50128  java.lang.ref.ReferenceQueue$Lock
  31:           984          47232  java.util.zip.Inflater
  32:           937          46024  [Ljava.lang.String;
  33:           792          45120  [Ljava.lang.reflect.Method;
  34:          1090          43600  java.lang.invoke.MethodType
  35:           939          37560  java.util.TreeMap$Entry
  36:          1152          36864  java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
  37:           752          36096  org.springframework.core.ResolvableType
  38:             1          32784  [Ljava.util.concurrent.ForkJoinTask;
  39:          1013          32416  java.util.concurrent.locks.ReentrantLock$NonfairSync
  40:          1094          26256  java.util.ArrayList
  41:           806          25792  java.lang.invoke.DirectMethodHandle
  42:           128          24576  org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$ConfigurationClassBeanDefinition
  43:           984          23616  java.util.zip.ZStreamRef
  44:           512          20480  org.springframework.util.ConcurrentReferenceHashMap$Segment
  45:           512          20088  [Lorg.springframework.util.ConcurrentReferenceHashMap$Reference;
  46:           351          19656  java.lang.Package
  47:           809          19416  sun.reflect.annotation.AnnotationInvocationHandler
  48:           535          15720  [Ljava.lang.CharSequence;
  49:           487          15584  org.springframework.boot.loader.jar.AsciiBytes
  50:           475          15200  java.lang.invoke.LambdaForm$Name
...
Total        215157       10801024

Dump 文件生成

$ jmap -dump:format=b,file=./dump.hprof 30444
Dumping heap to E:\temp\dump.hprof ...
Heap dump file created

Dump 文件生成 - 存活对象

$ jmap -dump:live,format=b,file=./dump_live.hprof 30444
Dumping heap to E:\temp\dump_live.hprof ...
Heap dump file created

jhat

jhat 命令解析 Java 堆转储文件并启动 Web 服务器。* jhat* 命令允许您使用您喜欢的 *Web* 浏览器浏览堆转储。 *jhat* 命令支持预先设计的查询,例如显示已知类 *MyClass* 和对象查询语言 (*OQL*) 的所有实例。除了查询堆转储之外,*OQL* 与 *SQL* 类似。可以从 *jhat* 命令显示的 *OQL* 帮助页面获得有关 *OQL* 的帮助。使用默认端口,可在 http://localhost:7000/oqlhelp/ 获得 *OQL* 帮助

参数

参数 描述
`-stack false true`
`-refs false true`
-port port-number 设置 jhat HTTP 服务器的端口。默认值为 7000
-exclude exclude-file 指定一个文件,该文件列出应从可达对象查询中排除的数据成员。例如,如果文件列出了 java.lang.String.value ,那么无论何时计算从特定对象 o 可达的对象列表,都不会考虑涉及 java.lang.String.value 字段的引用路径。
-baseline exclude-file 指定基线堆转储。两个堆转储中具有相同对象 ID 的对象都被标记为不是新对象。其他对象被标记为新对象。这对于比较两个不同的堆转储很有用。
-debug int 设置此工具的调试级别。级别 0 表示没有调试输出。为更详细的模式设置更高的值。
-version 输出版本号并退出
-h 显示帮助消息并退出。
-help 显示帮助消息并退出。
-Jflag JVM 参数传递给运行 jhat 命令的 Java 虚拟机。例如,-J-Xmx512m 使用 512 MB 的最大堆大小。对于分析 Dump 大小较大的文件,需要将 JVM 调至 6GB 或更高。

使用

该命令将分析 dump_live.hprof 堆转储文件,并启动 Web 服务,发布至本地 8081 端口。

$ jhat -port 8081 dump_live.hprof
Reading from dump_live.hprof...
Dump file created Thu Aug 19 16:47:50 CST 2021
Snapshot read, resolving...
Resolving 188752 objects...
Chasing references, expect 37 dots.....................................
Eliminating duplicate references.....................................
Snapshot resolved.
Started HTTP server on port 8081
Server is ready.
Licensed under CC BY-NC-SA 4.0
最后更新于 Aug 20, 2021 14:22 +0800
Built with Hugo
Theme Stack designed by Jimmy