How to Use the jcmd Command for the JVM
This article will focus on the diagnostic command introduced with Java 9 as a command-line utility, jcmd. If the bin folder is on the path, you can invoke it by typing jcmd on the command line. Otherwise, you have to go to the bin directory or prepend the jcmd in your examples with the full or relative (to the location of your command line window) path to the bin folder.
If you open the bin folder of the Java installation, you can find quite a few command-line utilities there. These can be used to diagnose issues and monitor an application deployed with the Java Runtime Environment (JRE). They use different mechanisms to get the data they report. The mechanisms are specific to the Virtual Machine (VM) implementation, operating systems, and release. Typically, only a subset of these tools is applicable to a given issue.
If you do type it and there is no Java process currently running on the machine, you’ll get back only one line, as follows:
This shows that only one Java process is currently running (the jcmd utility itself) and it has the process identifier(PID) of 87863 (which will be different with each run).
Now run a Java program, for example:
java -cp ./cookbook-1.0.jar
The output of jcmd will show (with different PIDs) the following:
If entered without any options, the jcmd utility reports the PIDs of all the currently running Java processes. After getting the PID, you can then use jcmd to request data from the JVM that runs the process:
jcmd 88749 VM.version
Alternatively, you can avoid using PID (and calling jcmd without parameters) by referring to the process by the main class of the application:
jcmd Chapter11Memory VM.version
You can read the JVM documentation for more details about the jcmd utility and how to use it.
How to do it…
jcmd is a utility that allows you to issue commands to a specified Java process:
- Get the full list of the jcmdcommands available for a particular Java process by executing the following line:
jcmd PID/main-class-name help
Instead of PID/main-class, enter the process identifier or the main class name. The list is specific to JVM, so each listed command requests the data from the specific process.
- In JDK 8, the following jcmdcommands were available:
JDK 9 introduced the following jcmd commands (JDK 18.3 and JDK 18.9 did not add any new commands):
- queue: Prints the methods queued for compilation with either C1 or C2 (separate queues)
- codelist: Prints n-methods (compiled) with full signature, address range, and state (alive, non-entrant, and zombie), and allows the selection of printing to stdout, a file, XML, or text printout
- codecache: Prints the content of the code cache, where the JIT compiler stores the generated native code to improve performance
- directives_add file: Adds compiler directives from a file to the top of the directives stack
- directives_clear: Clears the compiler directives stack (leaves the default directives only)
- directives_print: Prints all the directives on the compiler directives stack from top to bottom
- directives_remove: Removes the top directive from the compiler directives stack
- heap_info: Prints the current heap parameters and status
- finalizer_info: Shows the status of the finalizer thread, which collects objects with a finalizer (that is, a finalize()method)
- configure: Allows configuring the Java Flight Recorder
- data_dump: Prints the Java Virtual Machine Tool Interface data dump
- agent_load: Loads (attaches) the Java Virtual Machine Tool Interface agent
- status: Prints the status of the remote JMX agent
- print: Prints all the threads with stack traces
- log [option]: Allows setting the JVM log configuration at runtime, after the JVM has started (the availability can be seen using VM.log list)
- info: Prints the unified JVM info (version and configuration), a list of all threads and their state (without thread dump and heap dump), heap summary, JVM internal events (GC, JIT, safepoint, and so on), memory map with loaded native libraries, VM arguments and environment variables, and details of the operation system and hardware
- dynlibs: Prints information about dynamic libraries
- set_flag: Allows setting the JVM writable(also called manageable) flags
- stringtableand VM.symboltable: Print all UTF-8 string constants
- class_hierarchy [full-class-name]: Prints all the loaded classes or just a specified class hierarchy
- classloader_stats: Prints information about the classloader
- print_touched_methods: Prints all the methods that have been touched (have been read at least) at runtime
As you can see, these new commands belong to several groups, denoted by the prefix compiler, garbage collector (GC), Java Flight Recorder (JFR), Java Virtual Machine Tool Interface (JVMTI), Management Agent (related to remote JMX agent), thread, and VM.
How it works…
- To get help for the jcmdutility, run the following command:
Here is the result of the command:
It tells you that the commands can also be read from the file specified after -f, and there is a PerfCounter.print command, which prints all the performance counters (statistics) of the process.
- Run the following command:
jcmd Chapter11Memory GC.heap_info
The output may look similar to this screenshot:
It shows the total heap size and how much of it was used, the size of a region in the young generation and how many regions are allocated, and the parameters of Metaspace and class space.
- The following command is very helpful in case you are looking for runaway threads or would like to know what else is going on behind the scenes:
jcmd Chapter11Memory Thread.print
Here is a fragment of the possible output:
- This command is probably used most often, as it produces a wealth of information about the hardware, the JVM process as a whole, and the current state of its components:
jcmd Chapter11Memory VM.info
It starts with a summary, as follows:
The general process description is as follows:
Then the details of the heap are shown (this is only a tiny fragment of it):
It then prints the compilation events, GC heap history, de-optimization events, internal exceptions, events, dynamic libraries, logging options, environment variables, VM arguments, and many parameters of the system running the process.
The jcmd commands give a deep insight into the JVM process, which helps to debug and tune the process for best performance and optimal resource usage.
If you found this article interesting, you can dive into Java 11 Cookbook – Second Edition to explore the new features added to Java 11 that will make your application modular, secure, and fast. Java 11 Cookbook – Second Edition offers a range of software development solutions with simple and straightforward Java 11 code examples to help you build a modern software system.