I like to use the command-line tools provided with the JDK in the early steps of analyzing performance and other issues with Java-based applications and have blogged on tools such as jcmd, jps, jstat, jinfo, jhat and jmap, jrunscript, jstack, and jdeps. JDK 9 is bringing new command-line tools with multiple tools specifically related to new JDK 9 features such as modularity (jlink and jmod) and enhanced deprecation (jdeprscan). In this post, I focus on a new command-line tool delivered with JDK 9 for dealing with performance and serviceability issues: jhsdb.
The jhsdb tool is described on its Oracle JDK 9 Documentation Early Access page, “You use the jhsdb tool to attach to a Java process or to launch a postmortem debugger to analyze the content of a core-dump from a crashed Java Virtual Machine (JVM).” The tool comes with several “modes” and several of these modes correspond in name and function with individual command-line tools available in previous JDK distributions. The
jhsdb tool not only provides a single tool that encompasses functionality of multiple other tools, but it also provides a single, consistent approach to applying these different functions. For example, the
jhsdb command-line syntax for getting help for each of the “modes” is identical.
jhsdb tool can be attached and applied to a running JVM (including one that is hanging) via its process identifier (PID) similar to how several other tools (including
jcmd) work. The
jhsdb tool can also be used to analyze core information associated with a crashed JVM if the core file and executable are provided. As an example of the consistency
jhsdb provides, all of its mode support the “common options”
--pid (to specify target JVM’s process ID),
--exe (to specify target executable),
--core (to specify target core dump file), and
--help (to display options specific to each mode).
The next series of snapshots demonstrates use of the
--help option with the main
jhsdb command and with each of several of
jhsdb‘s “modes.” One observation that can be made is that the common options
--exe are offered by all the modes. The obvious inference from this is that the specific functions supported in each mode are those other than those “common” options.
jhsdb “jstack” Mode
--help for the
jstack has two specific functionality options:
--mixed. These are demonstrated in the following two screen snapshots.
The screen snapshots just shown demonstrate that the
jstack mode of the
jhsdb tool provides us with deadlock detection details, information on thread locks, and an overview of the native frames and Java frames.
jhsdb “jmap” Mode
jmap shows several functions supported by that mode. When
jhsdb jmap is executed with only the
--pid or only with the
--core combination, the output is similar to that provided by the Linux pmap command.
As one would expect, the
jmap mode of the
jhsdb provides functions similar to those provided by the separate but similarly named jmap command. These include heap dump (
--heap), class histogram (
--histo), classloader statistics (
--clstats), and finalizer information (
--finalizerinfo) and are demonstrated in the following four screen snapshots.
jhsdb “jinfo” Mode
Not surprisingly, the
jinfo mode of the
jhsdb command provides functionality that overlaps with that provided by the jinfo command. Specifically, the
jinfo mode allows one to see the targeted JVM’s flags and system properties.
There are three main options used with
--flags to see JVM flags,
--sysprops to see the system properties, or no argument to see both the flags and the system properties. The next two screen snapshots demonstrate use of
jhsdb jinfo --flags and
jhsdb jinfo --sysprops. Running
jhsdb jinfo without any arguments shows the system properties first followed by the flags, but is not shown here.
jhsdb “jsnap” Mode
jsnap provides access to information previously provided by the internal class sun.jvm.hotspot.tools.JSnap which was previously available in
lib/sa-jdi.jar and which has been added to jhdsdb for JDK 9. There are two options for output from
jhsdb jsnap based on whether no mode-specific argument is provided or if the
--all mode-specific argument is provided. The next two screen snapshots demonstrate these two options.
These screenshots demonstrate that
jhsdb jsnap with no mode-specific option lists information such as events related to threads and class loading/unloading along with core JVM properties. Adding the
--all option lists these same properties, but in addition adds far more properties and, according to the documentation, “Prints all performance counters.”
By the way, Marcus Hirt’s Using the JVM Performance Counters provides an interesting look at how to apply JMX and custom MBeans to achieve a tool “similar to the PerformanceCounters MBean available in JRockit.” I believe that
jhsdb jsnap --all brings simple ability to see the same type of information in HotSpot as Hirt talked about being available in JRockit with
jhsdb Debug Modes
hsdb (graphical user interface for interactive debugging),
clhsdb (command-line interface for interactive debugging), and
debugd (remote debug server) are related to debug operations. I may take a closer look at these modes in a future post, but for now I simply show some screen snapshots that demonstrate the graphical interaction using
jhsdb hsdb. The GUI was started with
jhsdb hsdb --pid <pid> and most of the options displayed here were run by selecting the specific menu option under “Tools”.
As can be seen in the article HotSpot’s Hidden Treasure, the serviceability debugger GUI has been available before JDK 9 and
jhsdb, but this article also shows how much more difficult it was to find and start this tool before JDK 9’s introduction of
jcmd and to Other Command-line JDK Tools
I summarized the relationship of general-purpose tool
jcmd to other JDK-provided command-line tools in the blog post jcmd: One JDK Command-Line Tool to Rule Them All. I adapt that table here to add
jhsdb to the mix.
|Listing Java Processes||N/A1|
|Heap Usage Histogram|
(subset of locked thread frames)
|List System Properties|
|List VM Flags|
1 You use
jps -lm to identify PID upon which to have
jcmd, and many other tools act if working against a running JVM. I used
jcmd in this post to identify the PID, but the current jhsdb documentation demonstrates using
jps to acquire the JVM PID.
jhsdb tool is a mostly command-line tool that does also have an optional interactive GUI available that supports reporting of many of the commonly desired attributes of a JVM that is hung or has crashed. It provides a consistent interface across its modes and the command-line interaction allows for interactive help requests such that very little syntax must be known or remembered before applying the tool. If one can remember “
jhsdb“, one can start using the tool effectively. The
jhsdb tool is new to JDK 9, but brings functionality into one tool that was previously available from several different tools.