美文网首页
JVM-工具-jcmd

JVM-工具-jcmd

作者: terry蒋 | 来源:发表于2021-11-14 16:43 被阅读0次

    一、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)                             
    

    更具体的使用方法参考:

    JVM NativeMemoryTracking

    2.18 JFR 相关命令

    因为了解不多,暂且不介绍。

    三、参考

    JVM 性能调优工具 jcmd

    十二、jdk工具之jcmd介绍(堆转储、堆分析、获取系统信息、查看堆外内存

    JVM NativeMemoryTracking

    相关文章

      网友评论

          本文标题:JVM-工具-jcmd

          本文链接:https://www.haomeiwen.com/subject/dlgttrtx.html