JVM-工具-jcmd

一、jcmd 用法

1.1 基本知识

jcmd 是在 JDK1.7 以后,新增了一个命令行工具。

jcmd 是一个多功能的工具,相比 jstat 功能更为全面的工具,可用于获取目标 Java 进程的性能统计、JFR、内存使用、垃圾收集、线程堆栈、JVM 运行时间,也可以手动执行 GC、导出(TODO 能导出线程信息?)线程信息、堆信息等信息。

1.2 注意

1.2.1 jcmd 在 JDK1.7 以后才出现

1.2.2 jcmd 在旧的 jdk 版本中有些命令不支持

示例:

在1.8.0_73中不支持 GC.heap_info 参数:

# java -version
java version "1.8.0_73"
Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)
# jcmd 94666 GC.heap_info
94666:
java.lang.IllegalArgumentException: Unknown diagnostic command

但是 JDK 1.8.0_282 中支持 GC.heap_info 参数:

# java -version
openjdk version "1.8.0_282"
OpenJDK Runtime Environment (build 1.8.0_282-b08)
OpenJDK 64-Bit Server VM (build 25.282-b08, mixed mode)

# jcmd 20399 GC.heap_info   
20399:
 PSYoungGen      total 155136K, used 149434K [0x00000000ec400000, 0x00000000fb880000, 0x0000000100000000)
  eden space 154624K, 96% used [0x00000000ec400000,0x00000000f559aa80,0x00000000f5b00000)
  from space 512K, 65% used [0x00000000fb800000,0x00000000fb854010,0x00000000fb880000)
  to   space 11264K, 0% used [0x00000000fa280000,0x00000000fa280000,0x00000000fad80000)
 ParOldGen       total 52736K, used 25072K [0x00000000c4c00000, 0x00000000c7f80000, 0x00000000ec400000)
  object space 52736K, 47% used [0x00000000c4c00000,0x00000000c647c218,0x00000000c7f80000)
 Metaspace       used 42333K, capacity 43838K, committed 43992K, reserved 1087488K
  class space    used 5070K, capacity 5347K, committed 5376K, reserved 1048576K

二、jcmd 用法

下面以 1.8.0_282 版本 JDK 的 jcmd 命令进行说明

2.1 查看 help

# jcmd -help
Usage: jcmd <pid | main class> <command ...|PerfCounter.print|-f file>
   or: jcmd -l                                                    
   or: jcmd -h                                                    
                                                                  
  command must be a valid jcmd command for the selected jvm.      
  Use the command "help" to see which commands are available.   
  If the pid is 0, commands will be sent to all Java processes.   
  The main class argument will be used to match (either partially 
  or fully) the class used to start Java.                         
  If no options are given, lists Java processes (same as -p).     
                                                                  
  PerfCounter.print display the counters exposed by this process  
  -f  read and execute commands from the file                     
  -l  list JVM processes on the local machine                     
  -h  this help

参数描述

  • pid:[常用] 接收诊断命令请求的进程ID。

  • main class :**[不常用] **接收诊断命令请求的进程的main类。匹配进程时,main类名称中包含指定子字符串的任何进程均是匹配的。

    如果多个正在运行的Java进程共享同一个main类,诊断命令请求将会发送到所有的这些进程中。

  • command:[常用] 支持的子命令,示例:GC.class_stats、GC.class_histogram。

    注意: 如果任何参数含有空格,你必须使用英文的单引号或双引号将其包围起来。 此外,你必须使用转义字符来转移参数中的单引号或双引号,以阻止操作系统shell处理这些引用标记。当然,你也可以在参数两侧加上单引号,然后在参数内使用双引号(或者,在参数两侧加上双引号,在参数中使用单引号)。

  • Perfcounter.print:[不常用] 打印目标Java进程上可用的性能计数器。性能计数器的列表可能会随着Java进程的不同而产生变化。

  • -f file:[不常用] 从文件file中读取命令,然后在目标Java进程上调用这些命令。在file中,每个命令必须写在单独的一行。以"#"开头的行会被忽略。当所有行的命令被调用完毕后,或者读取到含有stop关键字的命令,将会终止对file的处理。

  • -l:[常用] 查看所有的进程列表信息。

  • -h:[常用] 查看帮助信息。(同 -help)

2.2 查看进程 jcmd -l【常用】

命令: jcmd -l

作用:查看 当前机器上所有的 jvm 进程信息。

同类作用的命令:jcmdjcmd -ljps -lm 这三个命令作用相同

示例:

# jcmd
5075 sun.tools.jcmd.JCmd
1255 org.tanukisoftware.wrapper.WrapperSimpleApp CloudResetPwdUpdateAgent
20399 /etc/java-app/springtest-0.0.1-SNAPSHOT.jar

# jps -lm
1255 org.tanukisoftware.wrapper.WrapperSimpleApp CloudResetPwdUpdateAgent
20399 /etc/java-app/springtest-0.0.1-SNAPSHOT.jar
5087 sun.tools.jps.Jps -lm

2.3 列出当前运行的 java 进程可以执行的操作【常用】

命令:jcmd <pid> help

作用:列出当前运行的 java 进程可以执行的操作

说明:不同的 jvm 进程 支持的操作可能是不一样的

示例:

# jcmd 20399 help
20399:
The following commands are available:
VM.unlock_commercial_features
JFR.configure
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help

For more information about a specific command use 'help <command>'.

2.4 查看具体命令的选项

命令:jcmd <pid> help command

作用:列出当前运行的 java 进程可以执行的操作

说明:不同的 jvm 进程 支持的操作可能是不一样的

示例:

# jcmd 20399 help GC.class_stats
20399:
GC.class_stats
Provide statistics about Java class meta data. Requires -XX:+UnlockDiagnosticVMOptions.

Impact: High: Depends on Java heap size and content.

Syntax : GC.class_stats [options] [<columns>]

Arguments:
        columns : [optional] Comma-separated list of all the columns to show. If not specified, the following columns are shown: InstBytes,KlassBytes,CpAll,annotations,MethodCount,Bytecodes,MethodAll,ROAll,RWAll,Total (STRING, no default value)

Options: (options must be specified using the <key> or <key>=<value> syntax)
        -all : [optional] Show all columns (BOOLEAN, false)
        -csv : [optional] Print in CSV (comma-separated values) format for spreadsheets (BOOLEAN, false)
        -help : [optional] Show meaning of all the columns (BOOLEAN, false)

2.5 查看内存信息【常用】

命令:jcmd <pid> GC.heap_info
作用:查看JVM内存信息,虽然名称为heap_info,但是除了堆内存信息,也会有堆外内存之一的Metaspace的信息。相比jstat命令结果会更直观一些。

示例:

# jcmd 6339 GC.heap_info
6339:
 PSYoungGen      total 162816K, used 72120K [0x00000000f5580000, 0x00000000fff80000, 0x0000000100000000)
  eden space 152576K, 43% used [0x00000000f5580000,0x00000000f96a3f68,0x00000000fea80000)
  from space 10240K, 52% used [0x00000000ff580000,0x00000000ffaca460,0x00000000fff80000)
  to   space 10752K, 0% used [0x00000000fea80000,0x00000000fea80000,0x00000000ff500000)
 ParOldGen       total 53760K, used 16098K [0x00000000e0000000, 0x00000000e3480000, 0x00000000f5580000)
  object space 53760K, 29% used [0x00000000e0000000,0x00000000e0fb8a00,0x00000000e3480000)
 Metaspace       used 37388K, capacity 38864K, committed 39040K, reserved 1083392K
  class space    used 4676K, capacity 4964K, committed 4992K, reserved 1048576K

2.6 查看性能统计信息

命令:jcmd <pid> PerfCounter.print
作用:查看指定进程的性能统计信息。

示例:

# jcmd 20399 PerfCounter.print
20399:
java.ci.totalTime=11018854737
java.cls.loadedClasses=7599
java.cls.sharedLoadedClasses=0
java.cls.sharedUnloadedClasses=0
java.cls.unloadedClasses=0
java.property.java.class.path="/etc/java-app/springtest-0.0.1-SNAPSHOT.jar"
java.property.java.endorsed.dirs="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-1.el7_9.x86_64/jre/lib/endorsed"
java.property.java.ext.dirs="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-1.el7_9.x86_64/jre/lib/ext:/usr/java/packages/lib/ext"
java.property.java.home="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-1.el7_9.x86_64/jre"
java.property.java.library.path="/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib"
java.property.java.version="1.8.0_282"
.......省略.......
.......省略.......
sun.zip.zipFile.openTime=1494230
sun.zip.zipFiles=50

2.7 VM.uptime

命令:jcmd <pid> VM.uptime
作用:查看 JVM 的已启动时长。

示例:

# jcmd 20399 VM.uptime 
20399:
18546050.327 s

2.8 GC.class_histogram【常用】

命令:jcmd <pid> GC.class_histogram
作用:查看系统中类统计信息。

同类作用的命令:和jmap -histo pid的效果是一样的,可以查看每个类的实例数量和占用空间大小。

示例:

# jcmd 20399 GC.class_histogram
20399:
 num     #instances         #bytes  class name
----------------------------------------------
   1:         46386        7235264  [C
   2:          2049        1781872  [B
   3:         45242        1085808  java.lang.String
   4:          8175         907288  java.lang.Class
   5:         24964         798848  java.util.concurrent.ConcurrentHashMap$Node
   6:          7448         655424  java.lang.reflect.Method
   7:          7453         388704  [Ljava.lang.Object;
   8:          7722         308880  java.util.LinkedHashMap$Entry
   9:         18231         291696  java.lang.Object
  10:          9050         289600  java.util.HashMap$Node
  11:          3159         288272  [I
  12:          3384         282568  [Ljava.util.HashMap$Node;
  13:           133         239888  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  14:          3377         189112  java.util.LinkedHashMap
  15:          5352         119768  [Ljava.lang.Class;
  16:          3219         103008  java.lang.ref.WeakReference
.......省略.......
.......省略.......
3027:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total        284762       18014944

2.9 Thread.print

命令:jcmd <pid> Thread.print
作用:查看线程堆栈信息。

同类作用的命令:和jstack -l作用一样

# jcmd 20399 Thread.print
20399:
2021-11-14 12:31:28
Full thread dump OpenJDK 64-Bit Server VM (25.282-b08 mixed mode):

"Attach Listener" #32 daemon prio=9 os_prio=0 tid=0x00007f89a0005000 nid=0x12ae waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

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

"http-nio-8099-AsyncTimeout" #29 daemon prio=5 os_prio=0 tid=0x00007f89c9e6c000 nid=0x4fcf waiting on condition [0x00007f897d9de000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1133)
        at java.lang.Thread.run(Thread.java:748)
.......省略.......
"VM Thread" os_prio=0 tid=0x00007f89c8158800 nid=0x4fb3 runnable 
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f89c805e000 nid=0x4fb1 runnable 
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f89c8060000 nid=0x4fb2 runnable 
"VM Periodic Task Thread" os_prio=0 tid=0x00007f89c81cb800 nid=0x4fba waiting on condition 
JNI global references: 952

2.10 GC.heap_dump

命令:jcmd <pid> GC.heap_dump FILE_NAME
作用:查看 JVM 的Heap Dump。导出的 dump 文件,可以使用MAT 或者 Visual VM 等工具进行分析(如果只指定文件名,默认会生成在启动 JVM 的目录里)

同类作用的命令:和 jmap -dump:format=b,file=heapdump.phrof pid 作用一样

示例:

# jcmd 20399 GC.heap_dump /root/test/dump.hprof
20399:
Heap dump file created

2.11 VM.system_properties

命令:jcmd <pid> VM.system_properties
作用:查看 JVM 的属性信息。

同类作用的命令:和jinfo -sysprops pid作用一样。jinfo pid会输出 VM.system_properties 和 VM.flags,命令短,更好记住,所以推荐直接使用jinfo pid

示例:

# jcmd 20399 VM.system_properties
20399:
#Sun Nov 14 12:39:36 CST 2021
java.runtime.name=OpenJDK Runtime Environment
java.protocol.handler.pkgs=org.springframework.boot.loader
sun.boot.library.path=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-1.el7_9.x86_64/jre/lib/amd64
java.vm.version=25.282-b08
java.vm.vendor=Red Hat, Inc.
java.vendor.url=https\://www.redhat.com/
.......省略.......
sun.io.unicode.encoding=UnicodeLittle
sun.cpu.endian=little
sun.cpu.isalist=

2.12 VM.flags

命令:jcmd <pid> VM.flags
作用:查看 JVM 的启动参数。

同类作用的命令:和jinfo -flags pid作用一样。jinfo pid会输出 VM.system_properties 和 VM.flags,命令短,更好记住,所以推荐直接使用jinfo pid

示例:

# jinfo -flags 20399   
Attaching to process ID 20399, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.282-b08
Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=62914560 -XX:MaxHeapSize=994050048 -XX:MaxNewSize=331350016 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=20971520 -XX:OldSize=41943040 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC

2.13 VM.command_line

命令:jcmd <pid> VM.command_line
作用:查看 JVM 的启动命令行。

示例:

# jcmd 6339 VM.command_line
6339:
VM Arguments:
jvm_args: -Xmx512m 
java_command: /etc/java-app/springtest-0.0.1-SNAPSHOT.jar
java_class_path (initial): /etc/java-app/springtest-0.0.1-SNAPSHOT.jar
Launcher Type: SUN_STANDARD

2.14 GC.run_finalization

命令:jcmd <pid> GC.run_finalization
作用: 对 JVM 执行 java.lang.System.runFinalization()。执行一次 finalization 操作,相当于执java.lang.System.runFinalization()。调用已经失去引用的对象的finalize方法,但是JVM可以选择执行或者不执行。

示例:

# jcmd 6339 GC.run_finalization
6339:
Command executed successfully

2.15 GC.run

命令:jcmd <pid> GC.run
作用:对 JVM 执行 java.lang.System.gc()。同 GC.run_finalization 告诉垃圾收集器打算进行垃圾收集,但是JVM可以选择执行或者不执行。

$ jcmd 22912 GC.run
22912:
Command executed successfully

2.16 VM.version

命令:jcmd <pid> VM.version
作用:查看目标jvm进程的版本信息。

示例:

# jcmd 6339 VM.version
6339:
OpenJDK 64-Bit Server VM version 25.282-b08
JDK 8.0_282

2.17 VM.native_memory

命令:jcmd <pid> VM.native_memory

jcmd <pid> VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB]
 
# summary: 分类内存使用情况.
# detail: 详细内存使用情况,除了summary信息之外还包含了虚拟内存使用情况。
# baseline: 创建内存使用快照,方便和后面做对比
# summary.diff: 和上一次baseline的summary对比
# detail.diff: 和上一次baseline的detail对比
# shutdown: 关闭NMT

作用:查看目标jvm进程的Native Memory Tracking (NMT)信息,用于追踪JVM的内部内存使用。

注意:

打开NMT会带来5%-10%的性能损耗

-XX:NativeMemoryTracking=xx参数必须放在 -jar 前面,示例:java -XX:NativeMemoryTracking=detail -jar -Xmn512m user.jar

使用 -XX:NativeMemoryTracking=summary 可以用于开启NMT,其中该值默认为off。
可以设置summary、detail来开启;开启的话,大概会增加5%-10%的性能消耗;使用-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics。
可以在jvm shutdown的时候输出整体的native memory统计;
其他的可以使用jcmd pid VM.native_memory相关命令进行查看、diff、shutdown等

整个memory主要包含了Java Heap、Class、Thread、Code、GC、Compiler、Internal、Other、Symbol、Native Memory Tracking、Arena Chunk这几部分;其中reserved表示应用可用的内存大小,committed表示应用正在使用的内存大小

示例:

备注:reserved表示应用可用的内存大小,committed表示应用正在使用的内存大小。

# jcmd 18787 VM.native_memory
18787:

Native Memory Tracking:

Total: reserved=1933966KB, committed=344310KB
-                 Java Heap (reserved=524288KB, committed=219136KB)
                            (mmap: reserved=524288KB, committed=219136KB) 
 
-                     Class (reserved=1087456KB, committed=43144KB)
                            (classes #7024) 说明:已经加载的classes个数
                            (malloc=4064KB #9142) 
                            (mmap: reserved=1083392KB, committed=39080KB) 
 
-                    Thread (reserved=29918KB, committed=29918KB)
                            (thread #30) 说明:表示线程个数
                            (stack: reserved=29784KB, committed=29784KB)
                            (malloc=102KB #174) 
                            (arena=32KB #56)
 
-                      Code (reserved=251838KB, committed=12834KB)说明:表示JIT生成的或者缓存的instructions占用
                            (malloc=2238KB #3799) 
                            (mmap: reserved=249600KB, committed=10596KB) 
 
-                        GC (reserved=22629KB, committed=21441KB)说明:目前已经占用的内存空间用于帮助GC
                            (malloc=3469KB #188) 
                            (mmap: reserved=19160KB, committed=17972KB) 
 
-                  Compiler (reserved=147KB, committed=147KB)
                            (malloc=15KB #327) 
                            (arena=133KB #5)
 
-                  Internal (reserved=5156KB, committed=5156KB)说明:表示命令行解析、JVMTI等占用
                            (malloc=5124KB #9478) 
                            (mmap: reserved=32KB, committed=32KB) 
 
-                    Symbol (reserved=10880KB, committed=10880KB) 说明:表示诸如string table及constant pool等symbol占用
                            (malloc=7771KB #70834) 
                            (arena=3109KB #1)
 
-    Native Memory Tracking (reserved=1478KB, committed=1478KB)
                            (malloc=7KB #80) 说明:表示该功能自身占用
                            (tracking overhead=1472KB)
 
-               Arena Chunk (reserved=176KB, committed=176KB) 说明:表示arena chunk占用
                            (malloc=176KB)                             

 



作者:terry蒋
链接:https://www.jianshu.com/p/011f0e3a39ff
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2022-08-02 10:37  菜菜聊架构  阅读(717)  评论(0编辑  收藏  举报