jcmd
is a JDK comes with an artifact, it is easy to profiling the Java program. Jcmd can actually replace a lot of commonly used tools, such as Jstak,jmap. Let us now understand what the jcmd,jcmd can do to help us locate the problem. How we use jcmd in our work.
From Jdk7 onwards, Jcmd is a tool that comes with the JDK. In the case where the JDK's path is properly configured, we can execute it directly at the command line jcmd
:
[root@vincent-testing ~]# jcmd -hUsage: 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
With Jcmd, we can do a lot of things, like grabbing a live stack (dump threads), grabbing runtime heap memory (dump heap), collecting GC logs, locating high CPU occupancy issues, and more.
List the JVM running on the machine
In the absence of jcmd, we also have a lot of methods to find out the JVM process, such as: Linux under the PS, the use of the JDK's own JPS and so on. With Jcmd, we can do the same:
[root@vincent-testing ~]# jcmd -l13714 sun.tools.jcmd.JCmd -l16324 org.rzo.yajsw.app.WrapperJVMMain9350 org.rzo.yajsw.app.WrapperJVMMain9815 org.apache.catalina.startup.Bootstrap start
jcmd -l
All Java programs can be listed with the same functionality as jps
in fact.
Operation of the specified JVM process
List all the JVM programs, find the process ID you are interested in, run jcmd <PID> help
it, and see what we can do:
[root@vincent-testing ~]# jcmd 9350 help9350:The following commands are available:JFR.stopJFR.startJFR.dumpJFR.checkVM.native_memoryVM.check_commercial_featuresVM.unlock_commercial_featuresManagementAgent.stopManagementAgent.start_localManagementAgent.startGC.rotate_logThread.printGC.class_statsGC.class_histogramGC.heap_dumpGC.run_finalizationGC.runVM.uptimeVM.flagsVM.system_propertiesVM.command_lineVM.versionhelpFor more information about a specific command use 'help <command>'.
As you can see, Jcmd provides us with a lot of features. Here, let's talk a few simple ones first.
Grab the field stack
It is believed that most Java programmers have used the jstack
jstack
thread stack that can dump the current JVM. jstack <PID> Thread.print
the same purpose can be achieved by:
➜~ jcmd 3426 thread.print3426:2018-08-02 21:36:07full Thread dump Java HotSpot (TM) 64-bit Server VM (25.144-b Mixed mode): "Attach Listener" #16 daemon prio=9 os_prio=31 tid=0x00007fd9a43d0000 nid=0xd07 waiting on condition [0x000 0000000000000] Java.lang.Thread.State:RUNNABLE "nettythreaddeathwatcher-2-1" #15 daemon prio=1 os_prio=31 tid= 0x00007fd9a4ca1800 nid=0xa903 waiting on condition [0x0000700005924000] Java.lang.Thread.State:TIMED_WAITING ( Sleeping) at Java.lang.Thread.sleep (Native Method) at Io.netty.util.threaddeathwatcher$watcher.run (Threaddeathwatch er.java:152) at Io.netty.util.concurrent.defaultthreadfactory$defaultrunnabledecorator.run ( defaultthreadfactory.java:144) at Java.lang.Thread.run (thread.java:748) "DESTROYJAVAVM" #14 prio=5 os_prio=31 tid= 0x00007fd9a3b7f800 nid=0x1a03 waiting on condition [0x0000000000000000] java.lang.Thread.State:RUNNABLE .... Other thre Ads ommited ...
If you want to include lock information in a thread dump, you need to add -l=true
:
➜ ~ jcmd 3426 Thread.print -l=true3426:2018-08-02 21:39:08Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode):"Attach Listener" #16 daemon prio=9 os_prio=31 tid=0x00007fd9a43d0000 nid=0xd07 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None"NettythreadDeathWatcher-2-1" #15 daemon prio=1 os_prio=31 tid=0x00007fd9a4ca1800 nid=0xa903 waiting on condition [0x0000700005924000] 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:144) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - None.... other threads ommited
Crawl Heap Memory
➜ ~ jcmd 3426 help GC.heap_dump3426:GC.heap_dumpGenerate a HPROF format dump of the Java heap.Impact: High: Depends on Java heap size and content. Request a full GC unless the '-all' option is specified.Permission: java.lang.management.ManagementPermission(monitor)Syntax : GC.heap_dump [options] <filename>Arguments: filename : Name of the dump file (STRING, no default value)Options: (options must be specified using the <key> or <key>=<value> syntax) -all : [optional] Dump all objects, including unreachable objects (BOOLEAN, false)
If you have a problem with memory leaks, you know how to dump heap memory, or see the class distribution in heap memory. The usual tool we used before was jmap
to use Jcmd to dump heap memory GC.heap_dump
.
➜ ~ jcmd 3426 GC.heap_dump test.dump3426:Heap dump file created
Typically, in dump heap memory money will trigger a full GC, and if you do not want to trigger the full GC, you can specify the parameters all=true
, namely:
➜ ~ jcmd 3426 GC.heap_dump test2.dump -all=true3426:Heap dump file created
Memory usage of the statistics heap
Dump heap memory and analysis is relatively complex, an easier way is to count the histogram of objects in the heap. In the absence of jcmd, I usually use Jmap to count the distribution of objects in the heap, if I want to use the distribution of objects in the Jcmd statistics heap jcmd <PID> GC.class_histogram
.
There are many other tools in the Jcmd command, and if you are interested, you can jcmd <PID> help <command>
view them. Before Jcmd tools are used, we often need to combine several different tools for problem locating, and now only need to use jcmd one command. In addition to replacing existing tools, Jcmd also supports more advanced profiling features, recording JFR to analyze the performance of the JVM.
[Article sync posted on my personal blog, welcome to shoot bricks.
Portal: JVM problem-locating Swiss Army knife--jcmd