JVM 性能调优工具 jcmd

简介: 在JDK1.7以后,新增了一个命令行工具 jcmd。他是一个多功能的工具,可以用它来导出堆、查看Java进程、导出线程信息、执行GC、还可以进行采样分析(jmc 工具的飞行记录器)。

jcmd 用法

$ 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:接收诊断命令请求的进程的main类。匹配进程时,main类名称中包含指定子字符串的任何进程均是匹配的。如果多个正在运行的Java进程共享同一个main类,诊断命令请求将会发送到所有的这些进程中。
    注意: 如果任何参数含有空格,你必须使用英文的单引号或双引号将其包围起来。 此外,你必须使用转义字符来转移参数中的单引号或双引号,以阻止操作系统shell处理这些引用标记。当然,你也可以在参数两侧加上单引号,然后在参数内使用双引号(或者,在参数两侧加上双引号,在参数中使用单引号)。
  • Perfcounter.print:打印目标Java进程上可用的性能计数器。性能计数器的列表可能会随着Java进程的不同而产生变化。
  • -f file:从文件file中读取命令,然后在目标Java进程上调用这些命令。在file中,每个命令必须写在单独的一行。以"#"开头的行会被忽略。当所有行的命令被调用完毕后,或者读取到含有stop关键字的命令,将会终止对file的处理。
  • -l:查看所有的进程列表信息。
  • -h:查看帮助信息。(同 -help)

查看进程 jcmd -l

命令:jcmd -l
描述:查看 当前机器上所有的 jvm 进程信息。

jcmd
jcmd -l
jps -m

这三个命令的效果是一样的

查看性能统计

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

$ jcmd 22912 PerfCounter.print
22912:
java.ci.totalTime=45473763
java.cls.loadedClasses=3350
java.cls.sharedLoadedClasses=0
java.cls.sharedUnloadedClasses=0
java.cls.unloadedClasses=0
java.property.java.class.path="D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/jps-launcher.jar;D:/Program Files/Java/jdk1.8.0_161/lib/tools.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/optimizedFileManager.jar"
java.property.java.endorsed.dirs=""""
java.property.java.ext.dirs="D:\Program Files\Java\jdk1.8.0_161\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext"
java.property.java.home="D:\Program Files\Java\jdk1.8.0_161\jre"
...

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

命令:jcmd <pid> help

$ jcmd 22912 help
22912:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.run_finalization
GC.run
VM.uptime
VM.flags
VM.system_properties
VM.command_line
VM.version
help

查看具体命令的选项

如果想查看命令的选项,比如想查看 JFR.dump 命令选项,可以通过如下命令: jcmd <pid> help JFR.dump

$ jcmd 22912 help JFR.dump
22912:
JFR.dump
Copies contents of a JFR recording to file. Either the name or the recording id must be specified.

Impact: Low

Permission: java.lang.management.ManagementPermission(monitor)

Syntax : JFR.dump [options]

Options: (options must be specified using the <key> or <key>=<value> syntax)
        name : [optional] Recording name, e.g. \"My Recording\" (STRING, no default value)
        recording : [optional] Recording number, use JFR.check to list available recordings (JLONG, -1)
        filename :  Copy recording data to file, i.e \"C:\Users\user\My Recording.jfr\" (STRING, no default value)
        compress : [optional] GZip-compress "filename" destination (BOOLEAN, false)

JFR 相关命令

JFR 功能跟 jmc.exe 工具的飞行记录器的功能一样的。
要使用 JFR 相关的功能,必须使用 VM.unlock_commercial_features 参数取消锁定商业功能。

$ jcmd 22912 JFR.start
22912:
Java Flight Recorder not enabled.

Use VM.unlock_commercial_features to enable.

jmc.exe 显示的提示
image

  • 启动JFR
    执行命令:jcmd $PID JFR.start name=abc,duration=120s
  • Dump JFR
    等待至少duration(本文设定120s)后,执行命令:jcmd PID JFR.dump name=abc,duration=120s filename=abc.jfr(注意,文件名必须为.jfr后缀)
  • 检查JFR状态
    执行命令:jcmd $PID JFR.check name=abc,duration=120s
  • 停止JFR
    执行命令:jcmd $PID JFR.stop name=abc,duration=120s
  • JMC分析
    切回开发机器,下载步骤3中生成的abc.jfr,打开jmc,导入abc.jfr即可进行可视化分析

VM.uptime

命令:jcmd <pid> VM.uptime
描述:查看 JVM 的启动时长。

$ jcmd 22912 VM.uptime
22912:
266194.602 s

GC.class_histogram

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

$ jcmd 22912 GC.class_histogram
22912:

 num     #instances         #bytes  class name
----------------------------------------------
   1:           649       17000784  [B
   2:         19299        1799336  [C
   3:          7474         475320  [Ljava.lang.Object;
   4:         19116         458784  java.lang.String
   5:          3603         402048  java.lang.Class
   6:          6979         223328  java.util.concurrent.ConcurrentHashMap$Node
   7:          4405         140960  java.util.HashMap$Node
   8:          2372         113856  gnu.trove.THashMap
   9:          6447         103152  java.lang.Object
  10:          1428          98088  [I
  11:            47          58064  [Ljava.util.concurrent.ConcurrentHashMap$Node;

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

Thread.print

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

$ jcmd 22912 Thread.print
22912:
2019-05-13 13:23:42
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode):

"NettythreadDeathWatcher-2-1" #17 daemon prio=1 os_prio=-2 tid=0x00000000178f0800 nid=0x8190 waiting on condition [0x0000000018faf000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at io.netty.util.ThreadDeathWatcher$Watcher.run(ThreadDeathWatcher.java:152)
        at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
        at java.lang.Thread.run(Thread.java:748)

"DestroyJavaVM" #15 prio=5 os_prio=0 tid=0x00000000178f1800 nid=0x67d4 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"JPS event loop" #10 prio=5 os_prio=0 tid=0x0000000016ab4800 nid=0x1a80 runnable [0x00000000170ae000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
        at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x00000000d5419030> (a io.netty.channel.nio.SelectedSelectionKeySet)
        - locked <0x00000000d5419020> (a java.util.Collections$UnmodifiableSet)
        - locked <0x00000000d5418fa0> (a sun.nio.ch.WindowsSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62)
        at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:752)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:408)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
        at java.lang.Thread.run(Thread.java:748)

该命令同 jstack 命令。

GC.heap_dump

命令:jcmd <pid> GC.heap_dump FILE_NAME
描述:查看 JVM 的Heap Dump。

$ jcmd 22912 GC.heap_dump d:\dump.hprof
22912:
Heap dump file created

跟 jmap命令:jmap -dump:format=b,file=heapdump.phrof pid 效果一样。导出的 dump 文件,可以使用MAT 或者 Visual VM 等工具进行分析(如果只指定文件名,默认会生成在启动 JVM 的目录里)。

VM.system_properties

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

$ jcmd 22912 VM.system_properties
22912:
#Mon May 13 13:28:38 CST 2019
java.vendor=Oracle Corporation
preload.project.path=D\:/WorkSpace/hqev/rbac
sun.java.launcher=SUN_STANDARD
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
sun.nio.ch.bugLevel=
idea.config.path=D\:/Program Files/JetBrains/IntelliJIdeaConfig/config
idea.paths.selector=IntelliJIdea2018.1
kotlin.daemon.client.alive.path="C\:\\Users\\Victor.Zxy\\AppData\\Local\\Temp\\kotlin-idea-3229673183181290493-is-running"
os.name=Windows 10
sun.boot.class.path=D\:\\Program Files\\Java\\jdk1.8.0_161\\jre\\lib\\resources.jar;D\:\\Program Files\\Java\\jdk1.8.0_161\\jre\\lib\\rt.jar;D\:\\Program Files\\Java\\jdk1.8.0_161\\jre\\lib\\sunrsasign.jar;D\:\\Program Files\\Java\\jdk1.8.0_161\\jre\\lib\\jsse.jar;D\:\\Program Files\\Java\\jdk1.8.0_161\\jre\\lib\\jce.jar;D\:\\Program Files\\Java\\jdk1.8.0_161\\jre\\lib\\charsets.jar;D\:\\Program Files\\Java\\jdk1.8.0_161\\jre\\lib\\jfr.jar;D\:\\Program Files\\Java\\jdk1.8.0_161\\jre\\classes
sun.desktop=windows
idea.plugins.path=D\:/Program Files/JetBrains/IntelliJIdeaConfig/config/plugins
java.vm.specification.vendor=Oracle Corporation
java.runtime.version=1.8.0_161-b12
io.netty.serviceThreadPrefix=Netty
user.name=Victor.Zxy
kotlin.incremental.compilation=true
idea.home.path=D\:\\Program Files\\JetBrains\\IntelliJ IDEA 2018.1
user.language=zh
jdt.compiler.useSingleThread=true
sun.boot.library.path=D\:\\Program Files\\Java\\jdk1.8.0_161\\jre\\bin
java.version=1.8.0_161
user.timezone=Asia/Shanghai

VM.flags

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

$ jcmd 22912 VM.flags
22912:
-XX:CICompilerCount=3 -XX:InitialHeapSize=335544320 
-XX:MaxHeapSize=734003200 -XX:MaxNewSize=244318208 
-XX:MinHeapDeltaBytes=524288 -XX:NewSize=111673344 
-XX:OldSize=223870976 -XX:-PrintGC -XX:+UseCompressedClassPointers 
-XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps 
-XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC

VM.command_line

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

$ jcmd 22912 VM.command_line
22912:
VM Arguments:
jvm_args: -Xmx700m -Djava.awt.headless=true -Djava.endorsed.dirs="" -Djdt.compiler.useSingleThread=true -Dpreload.project.path=D:/WorkSpace/hqev/rbac -Dpreload.config.path=D:/Program Files/JetBrains/IntelliJIdeaConfig/config/options -Dcompile.parallel=false -Drebuild.on.dependency.change=true -Djava.net.preferIPv4Stack=true -Dio.netty.initialSeedUniquifier=8246017585702392224 -Dfile.encoding=UTF-8 -Duser.language=zh -Duser.country=CN -Didea.paths.selector=IntelliJIdea2018.1 -Didea.home.path=D:\Program Files\JetBrains\IntelliJ IDEA 2018.1 -Didea.config.path=D:/Program Files/JetBrains/IntelliJIdeaConfig/config -Didea.plugins.path=D:/Program Files/JetBrains/IntelliJIdeaConfig/config/plugins -Djps.log.dir=D:/Program Files/JetBrains/IntelliJIdeaConfig/system/log/build-log -Djps.fallback.jdk.home=D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/jre64 -Djps.fallback.jdk.version=1.8.0_152-release -Dio.netty.noUnsafe=true -Djava.io.tmpdir=D:/Program Files/JetBrains/IntelliJIdeaConfig/system/compile-server/rbac_aca57a50/_temp_ -Djps.backward.ref.index.builder=true -Dkotlin.incremental.compilation=true -Dkotlin.daemon.enabled -Dkotlin.daemon.client.alive.path="C:\Users\Victor.Zxy\AppData\Local\Temp\kotlin-idea-3229673183181290493-is-running"
java_command: org.jetbrains.jps.cmdline.Launcher D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/jps-builders.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/annotations.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/trove4j.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/resources_en.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/protobuf-java-3.0.0.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/idea_rt.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/commons-logging-1.2.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/slf4j-api-1.7.10.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/asm-all.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/lz4-java-1.3.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/javac2.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/aether-1.1.0-all.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/httpcore-4.4.5.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/guava-21.0.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/jna.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/oro-2.0.8.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/jps-model.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/jps-builders-6.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/util.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/nanoxml-2.2.3.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/httpclient-4.5.2.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/jna-platform.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/forms_rt.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/aether-dependency-resolver.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/jgoodies-forms.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/snappy-in-java-0.5.1.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/maven-aether-provider-3.3.9-all.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/commons-cod
java_class_path (initial): D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/jps-launcher.jar;D:/Program Files/Java/jdk1.8.0_161/lib/tools.jar;D:/Program Files/JetBrains/IntelliJ IDEA 2018.1/lib/optimizedFileManager.jar
Launcher Type: SUN_STANDARD

GC.run_finalization

命令:jcmd <pid> GC.run_finalization
描述: 对 JVM 执行 java.lang.System.runFinalization()

$ jcmd 22912 GC.run_finalization
22912:
Command executed successfully

执行一次finalization操作,相当于执行java.lang.System.runFinalization()

GC.run

命令:jcmd <pid> GC.run
描述:对 JVM 执行 java.lang.System.gc()

$ jcmd 22912 GC.run
22912:
Command executed successfully

告诉垃圾收集器打算进行垃圾收集,而垃圾收集器进不进行收集是不确定的。

PerfCounter.print

命令:jcmd <pid> PerfCounter.print
描述:查看 JVM 性能相关的参数。

$ jcmd 22912 PerfCounter.print
22912:
java.ci.totalTime=45606938
java.cls.loadedClasses=3363
java.cls.sharedLoadedClasses=0
java.cls.sharedUnloadedClasses=0
java.cls.unloadedClasses=9
...

VM.version

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

$ jcmd 22912 VM.version
22912:
Java HotSpot(TM) 64-Bit Server VM version 25.161-b12
JDK 8.0_161
相关文章
|
6天前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。
|
4天前
|
监控 Java 编译器
Java虚拟机调优实战指南####
本文深入探讨了Java虚拟机(JVM)的调优策略,旨在帮助开发者和系统管理员通过具体、实用的技巧提升Java应用的性能与稳定性。不同于传统摘要的概括性描述,本文摘要将直接列出五大核心调优要点,为读者提供快速预览: 1. **初始堆内存设置**:合理配置-Xms和-Xmx参数,避免频繁的内存分配与回收。 2. **垃圾收集器选择**:根据应用特性选择合适的GC策略,如G1 GC、ZGC等。 3. **线程优化**:调整线程栈大小及并发线程数,平衡资源利用率与响应速度。 4. **JIT编译器优化**:利用-XX:CompileThreshold等参数优化即时编译性能。 5. **监控与诊断工
|
15天前
|
存储 监控 Java
JVM进阶调优系列(8)如何手把手,逐行教她看懂GC日志?| IT男的专属浪漫
本文介绍了如何通过JVM参数打印GC日志,并通过示例代码展示了频繁YGC和FGC的场景。文章首先讲解了常见的GC日志参数,如`-XX:+PrintGCDetails`、`-XX:+PrintGCDateStamps`等,然后通过具体的JVM参数和代码示例,模拟了不同内存分配情况下的GC行为。最后,详细解析了GC日志的内容,帮助读者理解GC的执行过程和GC处理机制。
|
23天前
|
Arthas 监控 数据可视化
JVM进阶调优系列(7)JVM调优监控必备命令、工具集合|实用干货
本文介绍了JVM调优监控命令及其应用,包括JDK自带工具如jps、jinfo、jstat、jstack、jmap、jhat等,以及第三方工具如Arthas、GCeasy、MAT、GCViewer等。通过这些工具,可以有效监控和优化JVM性能,解决内存泄漏、线程死锁等问题,提高系统稳定性。文章还提供了详细的命令示例和应用场景,帮助读者更好地理解和使用这些工具。
|
29天前
|
监控 架构师 Java
JVM进阶调优系列(6)一文详解JVM参数与大厂实战调优模板推荐
本文详述了JVM参数的分类及使用方法,包括标准参数、非标准参数和不稳定参数的定义及其应用场景。特别介绍了JVM调优中的关键参数,如堆内存、垃圾回收器和GC日志等配置,并提供了大厂生产环境中常用的调优模板,帮助开发者优化Java应用程序的性能。
|
1月前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
49 2
|
1月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
43 3
|
1月前
|
小程序 Oracle Java
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
这篇文章是关于JVM基础知识的介绍,包括JVM的跨平台和跨语言特性、Class文件格式的详细解析,以及如何使用javap和jclasslib工具来分析Class文件。
41 0
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
|
1月前
|
算法 Java
JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
本文详细介绍了JVM中的GC算法,包括年轻代的复制算法和老年代的标记-整理算法。复制算法适用于年轻代,因其高效且能避免内存碎片;标记-整理算法则用于老年代,虽然效率较低,但能有效解决内存碎片问题。文章还解释了这两种算法的具体过程及其优缺点,并简要提及了其他GC算法。
 JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
|
30天前
|
Java
JVM进阶调优系列(5)CMS回收器通俗演义一文讲透FullGC
本文介绍了JVM中CMS垃圾回收器对Full GC的优化,包括Stop the world的影响、Full GC触发条件、GC过程的四个阶段(初始标记、并发标记、重新标记、并发清理)及并发清理期间的Concurrent mode failure处理,并简述了GC roots的概念及其在GC中的作用。