Documentation Contents
Java Platform, Standard Edition HotSpot Virtual Machine Troubleshooting Guide
Contents    Previous    Next

2 Detailed Tool Descriptions

This chapter describes in detail the troubleshooting tools that are available in JDK 7 and tools specific to various operating systems. The chapter also explains how you can develop new tools using the application programing interfaces (APIs) provided by JDK 7.

This chapter contains the following sections:

HPROF

HPROF is a tool for heap and CPU profiling shipped with every JDK release. It is a dynamically linked library (DLL) that interfaces with the Java Virtual Machine (JVM) using the Java Virtual Machine Tools Interface (JVM TI). The tool writes profiling information either to a file or to a socket in ASCII or binary format. This information can be further processed by a profiler front-end tool.

The HPROF tool is capable of presenting CPU usage, heap allocation statistics, and monitor contention profiles. In addition, it can report complete heap dumps and states of all the monitors and threads in the JVM. In terms of diagnosing problems, HPROF is useful when analyzing performance, lock contention, memory leaks, and other issues.

In addition to the HPROF library, the JDK release includes the source for HPROF as JVM TI demonstration code. This code is located in the $JAVA_HOME/demo/jvmti/hprof directory.

The HPROF tool is invoked as follows:

$ java -agentlib:hprof ToBeProfiledClass

Depending on the type of profiling requested, HPROF instructs the JVM to send it the relevant events. The tool then processes the event data into profiling information. For example, the following command obtains the heap allocation profile:

$ java -agentlib:hprof=heap=sites ToBeProfiledClass

The complete list of options is printed when the HPROF agent is provided with the help option, as shown below.

$ java -agentlib:hprof=help
     HPROF: Heap and CPU Profiling Agent (JVMTI Demonstration Code)
hprof usage: java -agentlib:hprof=[help]|[<option>=<value>, ...]
Option Name and Value  Description                    Default
---------------------  -----------                    -------
heap=dump|sites|all    heap profiling                 all
cpu=samples|times|old  CPU usage                      off
monitor=y|n            monitor contention             n
format=a|b             text(txt) or binary output     a
file=<file>            write data to file             java.hprof[{.txt}]
net=<host>:<port>      send data over a socket        off
depth=<size>           stack trace depth              4
interval=<ms>          sample interval in ms          10
cutoff=<value>         output cutoff point            0.0001
lineno=y|n             line number in traces?         y
thread=y|n             thread in traces?              n
doe=y|n                dump on exit?                  y
msa=y|n                Solaris micro state accounting n
force=y|n              force output to <file>         y
verbose=y|n            print messages about dumps     y
Obsolete Options
----------------
gc_okay=y|n
<>
Examples
--------
  - Get sample cpu information every 20 millisec, with a stack depth of 3:
      java -agentlib:hprof=cpu=samples,interval=20,depth=3 classname
  - Get heap usage information based on the allocation sites:
      java -agentlib:hprof=heap=sites classname
Notes
-----
  - The option format=b cannot be used with monitor=y.
  - The option format=b cannot be used with cpu=old|times.
  - Use of the -Xrunhprof interface can still be used, e.g.
       java -Xrunhprof:[help]|[<option>=<value>, ...]
    will behave exactly the same as:
       java -agentlib:hprof=[help]|[<option>=<value>, ...]
Warnings
--------
  - This is demonstration code for the JVMTI interface and use of BCI,
    it is not an official product or formal part of the JDK.
  - The -Xrunhprof interface will be removed in a future release.
  - The option format=b is considered experimental, this format may change
    in a future release.

By default, heap profiling information (sites and dump) is written out to java.hprof.txt (in ASCII) in the current working directory.

The output is normally generated when the JVM exits, although this can be disabled by setting the doe (dump on exit) option to n (doe=n). In addition, a profile is generated when Ctrl+\ (on Solaris OS and Linux) or Ctrl-Break (on Windows) is pressed. On Solaris OS and Linux a profile is also generated when a QUIT signal is received by a process (kill -QUIT pid). If Ctrl+\ or Ctrl-Break is pressed multiple times, multiple profiles are generated to the one file.

The output in most cases will contain IDs for traces, threads, and objects. Each type of ID will typically start with a different number than the other IDs. For example, traces might start with 300000.

Heap Allocation Profile (heap=sites)

The following is a heap allocation profile generated by running the Java compiler (javac) on a set of input files. Only parts of the profiler output are shown here.

$ javac -J-agentlib:hprof=heap=sites Hello.java
SITES BEGIN (ordered by live bytes) Wed Oct 4 13:13:42 2006
          percent          live          alloc'ed  stack class
 rank   self  accum     bytes objs     bytes  objs trace name
    1 44.13% 44.13%   1117360 13967  1117360 13967 301926 java.util.zip.ZipEntry
    2  8.83% 52.95%    223472 13967   223472 13967 301927 com.sun.tools.javac.util.List
    3  5.18% 58.13%    131088    1    131088     1 300996 byte[]
    4  5.18% 63.31%    131088    1    131088     1 300995 com.sun.tools.javac.util.Name[]

A crucial piece of information in the heap profile is the amount of allocation that occurs in various parts of the program. The SITES record above shows that 44.13% of the total space was allocated for the java.util.zip.ZipEntry objects.

A good way to relate allocation sites to the source code is to record the dynamic stack traces that led to the heap allocation. The following output shows another part of the profiler output. This output illustrates the stack traces referred to by the four allocation sites in output shown above.

TRACE 301926:
        java.util.zip.ZipEntry.<init>(ZipEntry.java:101)
        java.util.zip.ZipFile+3.nextElement(ZipFile.java:417)
        com.sun.tools.javac.jvm.ClassReader.openArchive(ClassReader.java:1374)
        com.sun.tools.javac.jvm.ClassReader.list(ClassReader.java:1631)
TRACE 301927:
        com.sun.tools.javac.util.List.<init>(List.java:42)
        com.sun.tools.javac.util.List.<init>(List.java:50)
        com.sun.tools.javac.util.ListBuffer.append(ListBuffer.java:94)
        com.sun.tools.javac.jvm.ClassReader.openArchive(ClassReader.java:1374)
TRACE 300996:
        com.sun.tools.javac.util.Name$Table.<init>(Name.java:379)
        com.sun.tools.javac.util.Name$Table.<init>(Name.java:481)
        com.sun.tools.javac.util.Name$Table.make(Name.java:332)
        com.sun.tools.javac.util.Name$Table.instance(Name.java:349)
TRACE 300995:
        com.sun.tools.javac.util.Name$Table.<init>(Name.java:378)
        com.sun.tools.javac.util.Name$Table.<init>(Name.java:481)
        com.sun.tools.javac.util.Name$Table.make(Name.java:332)
        com.sun.tools.javac.util.Name$Table.instance(Name.java:349)

Each frame in the stack trace contains a class name, a method name, a source file name, and the line number. The user can set the maximum number of frames collected by the HPROF agent. The default limit is four. Stack traces reveal not only which methods performed heap allocation, but also which methods were ultimately responsible for making calls that resulted in memory allocation.

Heap Dump Profile (heap=dump)

A heap dump can be obtained using the heap=dump option. The heap dump is in either ASCII or binary format, depending on the setting of the format option. Tools such as jhat (see "The jhat Utility") use the binary format and therefore the format=b option is required. When the binary format is specified, the dump includes primitive type instance fields and primitive array content.

The following command produces a complete dump in ASCII text format of the current live objects in the heap from executing the javac compiler:

$ javac -J-agentlib:hprof=heap=dump Hello.java

The output is a large file. It consists of the root set as determined by the garbage collector, and an entry for each Java object in the heap that can be reached from the root set. The following is a selection of records from a sample heap dump.

HEAP DUMP BEGIN (39793 objects, 2628264 bytes) Wed Oct 4 13:54:03 2006
ROOT 50000114 (kind=<thread>, id=200002, trace=300000)
ROOT 50000006 (kind=<JNI global ref>, id=8, trace=300000)
ROOT 50008c6f (kind=<Java stack>, thread=200000, frame=5)
:
CLS 50000006 (name=java.lang.annotation.Annotation, trace=300000)
    loader        90000001
OBJ 50000114 (sz=96, trace=300001, class=java.lang.Thread@50000106)
    name        50000116
    group        50008c6c
    contextClassLoader    50008c53
    inheritedAccessControlContext    50008c79
    blockerLock    50000115
OBJ 50008c6c (sz=48, trace=300000, class=java.lang.ThreadGroup@50000068)
    name        50008c7d
    threads    50008c7c
    groups        50008c7b
ARR 50008c6f (sz=16, trace=300000, nelems=1, 
     elem type=java.lang.String[]@5000008e)
    [0]        500007a5
CLS 5000008e (name=java.lang.String[], trace=300000)
    super        50000012
    loader        90000001
:
HEAP DUMP END

Each record is a ROOT, OBJ, CLS, or ARR to represent a root, an object instance, a class, or an array. The hexadecimal numbers are identifiers assigned by HPROF. These numbers are used to show the references from an object to another object. In the above example, the java.lang.Thread instance 50000114 has a reference to its thread group (50008c6c) and other objects.

In general, as the output is very large, it is necessary to use a tool to visualize or process the output of the heap dump. One such tool is jhat. See "The jhat Utility".

CPU Usage Sampling Profile (cpu=samples)

The HPROF tool can collect CPU usage information by sampling threads. The example below shows how to generate a CPU usage sampling profile by running the javac compiler.

$ javac -J-agentlib:hprof=cpu=samples Hello.java
CPU SAMPLES BEGIN (total = 462) Wed Oct 4 13:33:07 2006
rank   self  accum   count trace method
   1 49.57% 49.57%     229 300187 java.util.zip.ZipFile.getNextEntry
   2  6.93% 56.49%      32 300190 java.util.zip.ZipEntry.initFields
   3  4.76% 61.26%      22 300122 java.lang.ClassLoader.defineClass2
   4  2.81% 64.07%      13 300188 java.util.zip.ZipFile.freeEntry
   5  1.95% 66.02%       9 300129 java.util.Vector.addElement
   6  1.73% 67.75%       8 300124 java.util.zip.ZipFile.getEntry
   7  1.52% 69.26%       7 300125 java.lang.ClassLoader.findBootstrapClass
   8  0.87% 70.13%       4 300172 com.sun.tools.javac.main.JavaCompiler.<init>
   9  0.65% 70.78%       3 300030 java.util.zip.ZipFile.open
  10  0.65% 71.43%       3 300175 com.sun.tools.javac.main.JavaCompiler.<init>

...
CPU SAMPLES END

The HPROF agent periodically samples the stack of all running threads to record the most frequently active stack traces. The count field above indicates how many times a particular stack trace was found to be active. These stack traces correspond to the CPU usage hot spots in the application.

CPU Usage Times Profile (cpu=times)

The HPROF tool can collect CPU usage information by injecting code into every method entry and exit, thereby keeping track of exact method call counts and the time spent in each method. This process uses bytecode injection (BCI) and runs considerably slower than the cpu=samples option. Below is part of the CPU usage times profile output collected from a run of the javac compiler.

$ javac -J-agentlib:hprof=cpu=times Hello.java
CPU TIME (ms) BEGIN (total = 2082665289) Wed oct 4 13:43:42 2006
rank   self  accum   count trace method
   1  3.70%  3.70%       1 311243 com.sun.tools.javac.Main.compile
   2  3.64%  7.34%       1 311242 com.sun.tools.javac.main.Main.compile
   3  3.64% 10.97%       1 311241 com.sun.tools.javac.main.Main.compile
   4  3.11% 14.08%       1 311173 com.sun.tools.javac.main.JavaCompiler.compile
   5  2.54% 16.62%       8 306183 com.sun.tools.javac.jvm.ClassReader.listAll
   6  2.53% 19.15%      36 306182 com.sun.tools.javac.jvm.ClassReader.list
   7  2.03% 21.18%       1 307195 com.sun.tools.javac.comp.Enter.main
   8  2.03% 23.21%       1 307194 com.sun.tools.javac.comp.Enter.complete
   9  1.68% 24.90%       1 306392 com.sun.tools.javac.comp.Enter.classEnter
  10  1.68% 26.58%       1 306388 com.sun.tools.javac.comp.Enter.classEnter
...
CPU TIME (ms) END

In this output the count represents the true count of the number of times this method was entered, and the percentages represent a measure of thread CPU time spent in those methods.

Java VisualVM

Java VisualVM is one of the tools included in the JDK download (starting with JDK release 7 update 7). This tool is useful to Java application developers to troubleshoot applications and to monitor and improve the applications' performance. With Java VisualVM you can generate and analyze heap dumps, track down memory leaks, perform and monitor garbage collection, and perform lightweight memory and CPU profiling. The tool is also useful for tuning, heap sizing, offline analysis, and post-mortem diagnosis.

In addition, you can use existing plug-ins that expand the functionality of Java VisualVM. For example, most of the functionality of the JConsole tool is available via the MBeans tab and the JConsole plug-in wrapper tab. You can choose from a catalog of standard Java VisualVM plug-ins by choosing Plugins from the Tools menu in the main Java VisualVM window.

For more information, see the Java VisualVM documentation at

http://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/index.html

Java VisualVM allows you to perform the following troubleshooting activities:

When you start Java VisualVM, the main Application window opens, displaying a list of Java applications running on the local machine, a list of Java applications running on any connected remote machines, a list of any JVM core dumps that were taken and saved (with Solaris OS and Linux), and a list of any application snapshots that were taken and saved.

Java VisualVM will automatically detect and connect to the Java Management Extensions (JMX) agents for Java applications that are running on JDK 7 or that have been started with the correct system properties on version 5.0. In order for the tool to detect and connect to the agents on a remote machine, the jstatd daemon must be running on the remote machine (see "The jstatd Daemon"). In cases where Java VisualVM cannot automatically discover and connect to JMX agents that are running in a target application, the tool provides a means for you to explicitly create these connections.

JConsole

Another useful tool included in the JDK download is the JConsole monitoring tool. This tool is compliant with JMX. The tool uses the built-in JMX instrumentation in the JVM to provide information on the performance and resource consumption of running applications. Although the tool is included in the JDK download, it can also be used to monitor and manage applications deployed with the JRE.

The JConsole tool can attach to any Java application in order to display useful information such as thread usage, memory consumption, and details about class loading, runtime compilation, and the operating system.

This output helps with high-level diagnosis of problems such as memory leaks, excessive class loading, and running threads. It can also be useful for tuning and heap sizing.

In addition to monitoring, JConsole can be used to dynamically change several parameters in the running system. For example, the setting of the -verbose:gc option can be changed so that garbage collection trace output can be dynamically enabled or disabled for a running application.

The following list provides an idea of the data that can be monitored using the JConsole tool. Each heading corresponds to a tab pane in the tool.

JConsole can monitor both local applications and remote applications. If you start the tool with an argument specifying a JMX agent to connect to, the tool will automatically start monitoring the specified application.

To monitor a local application, execute the command jconsole pid, where pid is the process ID of the application.

To monitor a remote application, execute the command jconsole hostname:portnumber, where hostname is the name of the host running the application, and portnumber is the port number you specified when you enabled the JMX agent.

If you execute the jconsole command without arguments, the tool will start by displaying the New Connection window, where you specify the local or remote process to be monitored. You can connect to a different host at any time by using the Connection menu.

With the JDK 1.5 release, you must start the application to be monitored with the -Dcom.sun.management.jmxremote option. With the JDK 7 release, no option is necessary when starting the application to be monitored.

As an example of the output of the monitoring tool, the following screen shows a chart of heap memory usage.

Figure 2-1 Sample Output from JConsole

Description of Figure 2-1 follows
Description of "Figure 2-1 Sample Output from JConsole"

A complete tutorial on the JConsole tool is beyond the scope of this document. However, for more details on the monitoring and management capabilities, and how to use JConsole, see the Java SE Monitoring and Management Guide at

http://docs.oracle.com/javase/8/docs/technotes/guides/management/index.html

You can also refer to the jconsole command man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jconsole.html

The jdb Utility

The jdb utility is included in the JDK release as the example command-line debugger. The jdb utility uses the Java Debug Interface (JDI) to launch or connect to the target JVM. The source code for jdb is included in $JAVA_HOME/demo/jpda/examples.jar.

JDI is a high-level Java API that provides information useful for debuggers and similar systems that need access to the running state of a (usually remote) virtual machine. JDI is a component of the Java Platform Debugger Architecture (JPDA). See "Java Platform Debugger Architecture".

In JDI a connector is the means by which the debugger connects to the target JVM. The JDK release has traditionally shipped with connectors that launch and establish a debugging session with a target JVM, as well as connectors that are used for remote debugging (using TCP/IP or shared memory transports).

This JDK release also ships with several Serviceability Agent (SA) connectors that allow a Java language debugger to attach to a crash dump or hung process. This can be useful in determining what the application was doing at the time of the crash or hang.

These connectors are SACoreAttachingConnector, SADebugServerAttachingConnector, and SAPIDAttachingConnector.

These connectors are generally used with enterprise debuggers, such as the NetBeans integrated development environment (IDE) or commercial IDEs. The following subsections demonstrate how these connectors can be used with the jdb command-line debugger.

For detailed information about the connectors, see the "Connectors" section of the JPDA documentation at

http://docs.oracle.com/javase/8/docs/technotes/guides/jpda/conninv.html

The command jdb -listconnectors prints a list of the available connectors. The command jdb -help prints the command usage help.

For more information on the jdb utility, refer to the man pages:

Attaching to a Process

This example uses the SA PID Attaching Connector to attach to a process. The target process is not started with any special options, that is, the -agentlib:jdwp option is not required. When this connector attaches to a process it does so in read-only mode: the debugger can examine threads and the running application but it cannot change anything. The process is frozen while the debugger is attached.

The command in the following example instructs jdb to use a connector named sun.jvm.hotspot.jdi.SAPIDAttachingConnector. This is a connector name rather than a class name. The connector takes one argument named pid, whose value is the process ID of the target process (9302 in this example).

$ jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=9302

Initializing jdb ...
> threads
Group system:
  (java.lang.ref.Reference$ReferenceHandler)0xa Reference Handler unknown
  (java.lang.ref.Finalizer$FinalizerThread)0x9  Finalizer         unknown
  (java.lang.Thread)0x8                         Signal Dispatcher running
  (java.lang.Thread)0x7                         Java2D Disposer   unknown
  (java.lang.Thread)0x2                         TimerQueue        unknown
Group main:
  (java.lang.Thread)0x6                         AWT-XAWT          running
  (java.lang.Thread)0x5                         AWT-Shutdown      unknown
  (java.awt.EventDispatchThread)0x4             AWT-EventQueue-0  unknown
  (java.lang.Thread)0x3                         DestroyJavaVM     running
  (sun.awt.image.ImageFetcher)0x1               Image Animator 0  sleeping
  (java.lang.Thread)0x0                         Intro             running
> thread 0x7
Java2D Disposer[1] where
  [1] java.lang.Object.wait (native method)
  [2] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
  [3] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
  [4] sun.java2d.Disposer.run (Disposer.java:125)
  [5] java.lang.Thread.run (Thread.java:619)
Java2D Disposer[1] up 1
Java2D Disposer[2] where
  [2] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116)
  [3] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132)
  [4] sun.java2d.Disposer.run (Disposer.java:125)
  [5] java.lang.Thread.run (Thread.java:619)

In this example the threads command is used to get a list of all threads. Then a specific thread is selected with the thread 0x7 command, and the where command is used to get a thread dump. Next the up 1 command is used to move up one frame in the stack, and the where command is used again to get a thread dump.

Attaching to a Core File on the Same Machine

The SA Core Attaching Connector is used to attach the debugger to a core file. The core file may have been created after a crash (see "Troubleshooting System Crashes"). The core file can also be obtained by using the gcore command on Solaris OS or the gcore command in gdb on Linux. Because the core file is a snapshot of the process at the time the core file was created, the connector attaches in read-only mode: the debugger can examine threads and the running application at the time of the crash.

The following command is an example of using this connector:

$ jdb -connect sun.jvm.hotspot.jdi.SACoreAttachingConnector:javaExecutable=$JAVA_HOME/bin/java,core=core.20441

This command instructs jdb to use a connector named sun.jvm.hotspot.jdi.SACoreAttachingConnector. The connector takes two arguments: javaExecutable and core. The javaExecutable argument indicates the name of the Java binary. The core argument is the core file name (the core from the process with PID 20441 in this example).

Attaching to a Core File or a Hung Process from a Different Machine

In order to debug a core file that has been transported from another machine, the OS versions and libraries must match. In this case you can first run a proxy server called the SA Debug Server. Then, on the machine where the debugger is installed, you can use the SA Debug Server Attaching Connector to connect to the debug server.

In the example below, there are two machines: machine1 and machine2. A core file is available on machine1 and the debugger is available on machine2. The SA Debug Server is started on machine1 as follows.

$ jsadebugd $JAVA_HOME/bin/java core.20441

The jsadebugd command takes two arguments. The first argument is the name of the executable. In most cases this is java, but it can be another name (in the case of embedded VMs, for example). The second argument is the name of the core file. In this example the core file was obtained for a process with PID 20441 using the gcore utility.

On machine2, the debugger connects to the remote SA Debug Server using the SA Debug Server Attaching Connector, as with the following command:

$ jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector:debugServerName=machine1

This command instructs jdb to use a connector named sun.jvm.hotspot.jdi.SADebugServerAttachingConnector. The connector has one argument debugServerName, which is the hostname or IP address of the machine where the SA Debug Server is running.


Note:

The SA Debug Server can also be used to remotely debug a hung process. In that case it takes a single argument which is the PID of the process. In addition, if it is required to run multiple debug servers on the same machine, each one must be provided with a unique ID. With the SA Debug Server Attaching Connector, this ID is provided as an additional connector argument. For more information on these and other related details, see the JPDA documentation at

http://docs.oracle.com/javase/8/docs/technotes/guides/jpda/index.html


The jhat Utility

The jhat tool provides a convenient means to browse the object topology in a heap snapshot. This tool was introduced in the JDK 6 release to replace the Heap Analysis Tool (HAT).

For more information about the jhat utility, see the jhat man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jhat.html

The tool parses a heap dump in binary format, for example, a heap dump produced by jmap -dump.

This utility can help debug unintentional object retention. This term is used to describe an object that is no longer needed but is kept alive due to references through some path from the rootset. This can happen, for example, if an unintentional static reference to an object remains after the object is no longer needed, if an Observer or Listener fails to de-register itself from its subject when it is no longer needed, or if a Thread that refers to an object does not terminate when it should. Unintentional object retention is the Java language equivalent of a memory leak.

The tool provides a number of standard queries. For example, the Roots query displays all reference paths from the rootset to a specified object and is particularly useful for finding unnecessary object retention.

In addition to the standard queries, you can develop your own custom queries with the Object Query Language (OQL) interface.

When you issue the jhat command, the utility starts an HTTP server on a specified TCP port. You can then use any browser to connect to the server and execute queries on the specified heap dump.

The following example shows how to execute jhat to analyze a heap dump file named snapshot.hprof:

$ jhat snapshot.hprof
Started HTTP server on port 7000
Reading from java_pid2278.hprof...
Dump file created Fri May 19 17:18:38 BST 2006
Snapshot read, resolving...
Resolving 6162194 objects...
Chasing references, expect 12324 dots................................
Eliminating duplicate references.....................................
Snapshot resolved.
Server is ready.

At this point jhat has started an HTTP server on port 7000. Point your browser to http://localhost:7000 to connect to the jhat server.

When you are connected to the server, you can execute a standard query (see "Standard Queries") or create an OQL query (see "Custom Queries"). The All Classes query is displayed by default.

Standard Queries

This subsection describes the standard queries that you can execute once connected to the jhat server.

Custom Queries

You can develop your own custom queries with the built-in Object Query Language (OQL) interface. Click on the Execute OQL Query button on the first page to display the OQL query page, where you can create and execute your custom queries. The OQL Help facility describes the built-in functions, with examples.

The syntax of the select statement is as follows:

select JavaScript-expression-to-select [from [instanceof] classname identifier [where JavaScript-boolean-expression-to-filter]]

The following is an example of the select statement:

select s from java.lang.String s where s.count >= 100

Heap Analysis Hints

To get useful information from jhat often requires some knowledge of the application and in addition some knowledge about the libraries and APIs that it uses. However in general the tool can be used to answer two important questions:

The jinfo Utility

The jinfo command-line utility gets configuration information from a running Java process or crash dump and prints the system properties or the command-line flags that were used to start the JVM.

The utility can also use the jsadebugd daemon to query a process or core file on a remote machine. Note that the output takes longer to print in this case.

With the -flag option, the utility can dynamically set, unset, or change the value of certain JVM flags for the specified Java process. See "HotSpot VM Command-Line Options".

For more information on the jinfo utility, refer to the man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html

The following is an example of the output from a Java process with PID number 29620:

$ jinfo 29620
Attaching to process ID 29620, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.6.0-rc-b100
Java System Properties:

java.runtime.name = Java(TM) SE Runtime Environment
sun.boot.library.path = /usr/jdk/instances/jdk1.6.0/jre/lib/sparc
java.vm.version = 1.6.0-rc-b100
java.vm.vendor = Sun Microsystems Inc.
java.vendor.url = http://java.sun.com/
path.separator = :
java.vm.name = Java HotSpot(TM) Client VM
file.encoding.pkg = sun.io
sun.java.launcher = SUN_STANDARD
sun.os.patch.level = unknown
java.vm.specification.name = Java Virtual Machine Specification
user.dir = /home/js159705
java.runtime.version = 1.6.0-rc-b100
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
java.endorsed.dirs = /usr/jdk/instances/jdk1.6.0/jre/lib/endorsed
os.arch = sparc
java.io.tmpdir = /var/tmp/
line.separator =

java.vm.specification.vendor = Sun Microsystems Inc.
os.name = SunOS
sun.jnu.encoding = ISO646-US
java.library.path = /usr/jdk/instances/jdk1.6.0/jre/lib/sparc/client:/usr/jdk/instances/jdk1.6.0/jre/lib/sparc:
/usr/jdk/instances/jdk1.6.0/jre/../lib/sparc:/net/gtee.sfbay/usr/sge/sge6/lib/sol-sparc64:
/usr/jdk/packages/lib/sparc:/lib:/usr/lib
java.specification.name = Java Platform API Specification
java.class.version = 50.0
sun.management.compiler = HotSpot Client Compiler
os.version = 5.10
user.home = /home/js159705
user.timezone = US/Pacific
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = ISO646-US
java.specification.version = 1.6
java.class.path = /usr/jdk/jdk1.6.0/demo/jfc/Java2D/Java2Demo.jar
user.name = js159705
java.vm.specification.version = 1.0
java.home = /usr/jdk/instances/jdk1.6.0/jre
sun.arch.data.model = 32
user.language = en
java.specification.vendor = Sun Microsystems Inc.
java.vm.info = mixed mode, sharing
java.version = 1.6.0-rc
java.ext.dirs = /usr/jdk/instances/jdk1.6.0/jre/lib/ext:/usr/jdk/packages/lib/ext
sun.boot.class.path = /usr/jdk/instances/jdk1.6.0/jre/lib/resources.jar:
/usr/jdk/instances/jdk1.6.0/jre/lib/rt.jar:/usr/jdk/instances/jdk1.6.0/jre/lib/sunrsasign.jar:
/usr/jdk/instances/jdk1.6.0/jre/lib/jsse.jar:
/usr/jdk/instances/jdk1.6.0/jre/lib/jce.jar:/usr/jdk/instances/jdk1.6.0/jre/lib/charsets.jar:
/usr/jdk/instances/jdk1.6.0/jre/classes
java.vendor = Sun Microsystems Inc.
file.separator = /
java.vendor.url.bug = http://java.sun.com/cgi-bin/bugreport.cgi
sun.io.unicode.encoding = UnicodeBig
sun.cpu.endian = big
sun.cpu.isalist =

VM Flags:

If you start the target JVM with the -classpath and -Xbootclasspath arguments, the output from jinfo provides the settings for java.class.path and sun.boot.class.path. This information might be needed when investigating class loader issues.

In addition to obtaining information from a process, the jinfo tool can use a core file as input. On Solaris OS, for example, the gcore utility can be used to get a core file of the process in the above example. The core file will be named core.29620 and will be generated in the working directory of the process. The path to the Java executable and the core file must be specified as arguments to the jinfo utility, as in the following example:

$ jinfo $JAVA_HOME/bin/java core.29620

Sometimes the binary name will not be java. This occurs when the VM is created using the JNI invocation API. The jinfo tool requires the binary from which the core file was generated.

The jmap Utility

The jmap command-line utility prints memory related statistics for a running VM or core file.

The utility can also use the jsadebugd daemon to query a process or core file on a remote machine. Note that the output takes longer to print in this case.

If jmap is used with a process or core file without any command-line options, then it prints the list of shared objects loaded (the output is similar to the pmap utility on Solaris OS). For more specific information, you can use the options -heap, -histo, or -permstat. These options are described in the subsections that follow.

In addition, the JDK 7 release introduced the -dump:format=b,file=filename option, which causes jmap to dump the Java heap in binary HPROF format to a specified file. This file can then be analyzed with the jhat tool.

If the jmap pid command does not respond because of a hung process, the -F option can be used (on Solaris OS and Linux only) to force the use of the Serviceability Agent.

For more information on the jmap utility, see the man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html

Heap Configuration and Usage

The -heap option is used to obtain the following Java heap information:

  • Information specific to the garbage collection (GC) algorithm, including the name of the GC algorithm (for example, Parallel GC) and algorithm specific details (such as number of threads for parallel GC).

  • Heap configuration that might have been specified as command-line options or selected by the VM based on the machine configuration.

  • Heap usage summary. For each generation (area of the heap), the tool prints the total heap capacity, in-use memory, and available free memory. If a generation is organized as a collection of spaces (for example, the new generation), then a space-wise memory size summary is included.

The following example shows output from the jmap -heap command.

$ jmap -heap 29620
Attaching to process ID 29620, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.6.0-rc-b100

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 67108864 (64.0MB)
   NewSize          = 2228224 (2.125MB)
   MaxNewSize       = 4294901760 (4095.9375MB)
   OldSize          = 4194304 (4.0MB)
   NewRatio         = 8
   SurvivorRatio    = 8
   PermSize         = 12582912 (12.0MB)
   MaxPermSize      = 67108864 (64.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 2031616 (1.9375MB)
   used     = 70984 (0.06769561767578125MB)
   free     = 1960632 (1.8698043823242188MB)
   3.4939673639112905% used
Eden Space:
   capacity = 1835008 (1.75MB)
   used     = 36152 (0.03447723388671875MB)
   free     = 1798856 (1.7155227661132812MB)
   1.9701276506696428% used
From Space:
   capacity = 196608 (0.1875MB)
   used     = 34832 (0.0332183837890625MB)
   free     = 161776 (0.1542816162109375MB)
   17.716471354166668% used
To Space:
   capacity = 196608 (0.1875MB)
   used     = 0 (0.0MB)
   free     = 196608 (0.1875MB)
   0.0% used
tenured generation:
   capacity = 15966208 (15.2265625MB)
   used     = 9577760 (9.134063720703125MB)
   free     = 6388448 (6.092498779296875MB)
   59.98769400974859% used
Perm Generation:
   capacity = 12582912 (12.0MB)
   used     = 1469408 (1.401336669921875MB)
   free     = 11113504 (10.598663330078125MB)
   11.677805582682291% used

Heap Histogram

The jmap command with the -histo option can be used to obtain a class-wise histogram of the heap. Depending on the parameter specified, the jmap -histo command can print out the heap histogram for a running process or a core file.

When the command is executed on a running process, the tool prints the number of objects, memory size in bytes, and fully qualified class name for each class. Internal classes in the HotSpot VM are enclosed in angle brackets. The histogram is useful in understanding how the heap is used. To get the size of an object you must divide the total size by the count of that object type.

The following example shows output from the jmap -histo command when it is executed on a process with PID number 29620:

$ jmap -histo 29620
num   #instances    #bytes  class name
--------------------------------------
  1:      1414     6013016  [I
  2:       793      482888  [B
  3:      2502      334928  <constMethodKlass>
  4:       280      274976  <instanceKlassKlass>
  5:       324      227152  [D
  6:      2502      200896  <methodKlass>
  7:      2094      187496  [C
  8:       280      172248  <constantPoolKlass>
  9:      3767      139000  [Ljava.lang.Object;
 10:       260      122416  <constantPoolCacheKlass>
 11:      3304      112864  <symbolKlass>
 12:       160       72960  java2d.Tools$3
 13:       192       61440  <objArrayKlassKlass>
 14:       219       55640  [F
 15:      2114       50736  java.lang.String
 16:      2079       49896  java.util.HashMap$Entry
 17:       528       48344  [S
 18:      1940       46560  java.util.Hashtable$Entry
 19:       481       46176  java.lang.Class
 20:        92       43424  javax.swing.plaf.metal.MetalScrollButton
... more lines removed here to reduce output...
1118:         1           8  java.util.Hashtable$EmptyIterator
1119:         1           8  sun.java2d.pipe.SolidTextRenderer
Total    61297    10152040

When the jmap -histo command is executed on a core file, the tool prints the size, count, and class name for each class. Internal classes in the HotSpot VM are prefixed with an asterisk (*).

The following example shows output of the jmap -histo command when it is executed on a core file:

& jmap -histo /net/koori.sfbay/onestop/jdk/6.0/promoted/all/b100/binaries/solaris-sparcv9/bin/java core
Attaching to core core from executable /net/koori.sfbay/onestop/jdk/6.0/
promoted/all/b100/binaries/solaris-sparcv9/bin/java, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 1.6.0-rc-b100
Iterating over heap. This may take a while...
Heap traversal took 8.902 seconds.

Object Histogram:

Size    Count    Class description
-------------------------------------------------------
4151816    2941    int[]
2997816    26403    * ConstMethodKlass
2118728    26403    * MethodKlass
1613184    39750    * SymbolKlass
1268896    2011    * ConstantPoolKlass
1097040    2011    * InstanceKlassKlass
882048    1906    * ConstantPoolCacheKlass
758424    7572    char[]
733776    2518    byte[]
252240    3260    short[]
214944    2239    java.lang.Class
177448    3341    * System ObjArray
176832    7368    java.lang.String
137792    3756    java.lang.Object[]
121744    74    long[]
72960    160    java2d.Tools$3
63680    199    * ObjArrayKlassKlass
53264    158    float[]
... more lines removed here to reduce output...

Permanent Generation Statistics

The permanent generation is the area of the heap that holds all the reflective data of the virtual machine itself, such as class and method objects (also called "method area" in The Java Virtual Machine Specification).

Configuring the size of the permanent generation can be important for applications that dynamically generate and load a very large number of classes (for example, Java Server Pages/web containers). If an application loads "too many" classes, then it is possible it will abort with the following error:

Exception in thread thread_name java.lang.OutOfMemoryError: PermGen space

For a description of this and other variants of the OutOfMemoryError exception, see "Understanding the OutOfMemoryError Exception".

To get further information about the permanent generation, you can use the -permstat option of the jmap command to print statistics for the objects in the permanent generation. The following example shows output from the jmap -permstat command executed on a process with PID number 29620:

$ jmap -permstat 29620
Attaching to process ID 29620, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.6.0-rc-b100
12674 intern Strings occupying 1082616 bytes.
finding class loader instances ..Unknown oop at 0xd0400900
Oop's klass is 0xd0bf8408
Unknown oop at 0xd0401100
Oop's klass is null
done.
computing per loader stat ..done.
please wait.. computing liveness.........................................done.
class_loader    classes bytes   parent_loader   alive?  type

<bootstrap>     1846 5321080  null        live   <internal>
0xd0bf3828  0      0      null         live    sun/misc/Launcher$ExtClassLoader@0xd8c98c78
0xd0d2f370  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0c99280  1   1440      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b71d90  0      0   0xd0b5b9c0    live java/util/ResourceBundle$RBClassLoader@0xd8d042e8
0xd0d2f4c0  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b5bf98  1    920   0xd0b5bf38      dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0c99248  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f488  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b5bf38  6   11832  0xd0b5b9c0      dead    sun/reflect/misc/MethodUtil@0xd8e8e560
0xd0d2f338  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f418  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f3a8  1    904     null          dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b5b9c0  317 1397448 0xd0bf3828     live    sun/misc/Launcher$AppClassLoader@0xd8cb83d8
0xd0d2f300  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f3e0  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0ec3968  1   1440      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0e0a248  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0c99210  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f450  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f4f8  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0e0a280  1    904      null         dead    sun/reflect/DelegatingClassLoader@0xd8c22f50

total = 22      2186    6746816   N/A   alive=4, dead=18       N/A    

For each class loader object, the following details are printed:

The jps Utility

The jps utility lists the instrumented HotSpot VMs for the current user on the target system. The utility is very useful in environments where the VM is embedded, that is, it is started using the JNI Invocation API rather than the java launcher. In these environments it is not always easy to recognize the Java processes in the process list.

The following example demonstrates the usage of the jps utility.

$ jps
16217 MyApplication
16342 jps

The utility lists the virtual machines for which the user has access rights. This is determined by access-control mechanisms specific to the operating system. On Solaris OS, for example, if a non-root user executes the jps utility, the output is a list of the virtual machines that were started with that user's uid.

In addition to listing the PID, the utility provides options to output the arguments passed to the application's main method, the complete list of VM arguments, and the full package name of the application's main class. The jps utility can also list processes on a remote system if the remote system is running the jstatd daemon.

If you are running several Java Web Start applications on a system, they tend to look the same, as shown in the following example:

$ jps
1271 jps
     1269 Main
     1190 Main

In this case, use jps -m to distinguish them, as follows:

$ jps -m
1271 jps -m
     1269 Main http://bugster.central.sun.com/bugster.jnlp
     1190 Main http://webbugs.sfbay/IncidentManager/incident.jnlp

For more information on the jps utility, see the man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html

The utility is included in the JDK download for all operating system platforms supported by Sun.


Note:

The HotSpot instrumentation is not accessible on Windows 98 or Windows ME. In addition, the instrumentation might not be accessible on Windows if the temporary directory is on a FAT32 file system.


The jrunscript Utility

The jrunscript utility is a command-line script shell. It supports script execution in both interactive mode and in batch mode. By default, the shell uses JavaScript, but you can specify any other scripting language for which you supply the path to the script engines's JAR file of .class files.

Thanks to the communication between the Java language and the scripting language, the jrunscript utility supports an exploratory programming style.

For more information on the jrunscript utility, see the man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jrunscript.html

The jsadebugd Daemon

The Java Serviceability Agent Debug Daemon (jsadebugd) attaches to a Java process or to a core file and acts as a debug server. This utility is currently available only on Solaris OS and Linux. Remote clients such as jstack, jmap, and jinfo can attach to the server using Java Remote Method Invocation (RMI).

For more information on jsadebugd, see the man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jsadebugd.html

The jstack Utility

The jstack command-line utility attaches to the specified process or core file and prints the stack traces of all threads that are attached to the virtual machine, including Java threads and VM internal threads, and optionally native stack frames. The utility also performs deadlock detection.

The utility can also use the jsadebugd daemon to query a process or core file on a remote machine. Note that the output takes longer to print in this case.

A stack trace of all threads can be useful in diagnosing a number of issues such as deadlocks or hangs.

The JDK 7 release introduced the -l option, which instructs the utility to look for ownable synchronizers in the heap and print information about java.util.concurrent.locks. Without this option, the thread dump includes information only on monitors.

Starting with JDK 7, the output from the jstack pid option is the same as that obtained by pressing Ctrl+\ at the application console (standard input) or by sending the process a QUIT signal. See "Control+Break Handler" for an output example.

Thread dumps can also be obtained programmatically using the Thread.getAllStackTraces method, or in the debugger using the debugger option to print all thread stacks (the where command in the case of the jdb sample debugger).

For more information on the jstack utility, see the man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html

Forcing a Stack Dump

If the jstack pid command does not respond because of a hung process, the -F option can be used (on Solaris OS and Linux only) to force a stack dump, as in the following example:

$ jstack -F 8321
Attaching to process ID 8321, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.6.0-rc-b100
Deadlock Detection:

Found one Java-level deadlock:
=============================

"Thread2":
  waiting to lock Monitor@0x000af398 (Object@0xf819aa10, a java/lang/String),
  which is held by "Thread1"
"Thread1":
  waiting to lock Monitor@0x000af400 (Object@0xf819aa48, a java/lang/String),
  which is held by "Thread2"

Found a total of 1 deadlock.

Thread t@2: (state = BLOCKED)

Thread t@11: (state = BLOCKED)
 - Deadlock$DeadlockMakerThread.run() @bci=108, line=32 (Interpreted frame)

Thread t@10: (state = BLOCKED)
 - Deadlock$DeadlockMakerThread.run() @bci=108, line=32 (Interpreted frame)

Thread t@6: (state = BLOCKED)

Thread t@5: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=-1107318896 (Interpreted frame)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.ref.ReferenceQueue.remove(long) @bci=44, line=116 (Interpreted frame)
 - java.lang.ref.ReferenceQueue.remove() @bci=2, line=132 (Interpreted frame)
 - java.lang.ref.Finalizer$FinalizerThread.run() @bci=3, line=159 (Interpreted frame)

Thread t@4: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.Object.wait() @bci=2, line=485 (Interpreted frame)
 - java.lang.ref.Reference$ReferenceHandler.run() @bci=46, line=116 (Interpreted frame)

Printing Stack Trace From Core Dump

To obtain stack traces from a core dump, execute the jstack command on a core file, as follows:

$ jstack $JAVA_HOME/bin/java core

Printing a Mixed Stack

The jstack utility can also be used to print a mixed stack, that is, it can print native stack frames in addition to the Java stack. Native frames are the C/C++ frames associated with VM code and JNI/native code.

To print a mixed stack, use the -m option, as in the following example:

$ jstack -m 21177
Attaching to process ID 21177, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.6.0-rc-b100
Deadlock Detection:

Found one Java-level deadlock:
=============================

"Thread1":
  waiting to lock Monitor@0x0005c750 (Object@0xd4405938, a java/lang/String),
  which is held by "Thread2"
"Thread2":
  waiting to lock Monitor@0x0005c6e8 (Object@0xd4405900, a java/lang/String),
  which is held by "Thread1"

Found a total of 1 deadlock.

----------------- t@1 -----------------
0xff2c0fbc    __lwp_wait + 0x4
0xff2bc9bc    _thrp_join + 0x34
0xff2bcb28    thr_join + 0x10
0x00018a04    ContinueInNewThread + 0x30
0x00012480    main + 0xeb0
0x000111a0    _start + 0x108
----------------- t@2 -----------------
0xff2c1070    ___lwp_cond_wait + 0x4
0xfec03638    bool Monitor::wait(bool,long) + 0x420
0xfec9e2c8    bool Threads::destroy_vm() + 0xa4
0xfe93ad5c    jni_DestroyJavaVM + 0x1bc
0x00013ac0    JavaMain + 0x1600
0xff2bfd9c    _lwp_start
----------------- t@3 -----------------
0xff2c1070    ___lwp_cond_wait + 0x4
0xff2ac104    _lwp_cond_timedwait + 0x1c
0xfec034f4    bool Monitor::wait(bool,long) + 0x2dc
0xfece60bc    void VMThread::loop() + 0x1b8
0xfe8b66a4    void VMThread::run() + 0x98
0xfec139f4    java_start + 0x118
0xff2bfd9c    _lwp_start
----------------- t@4 -----------------
0xff2c1070    ___lwp_cond_wait + 0x4
0xfec195e8    void os::PlatformEvent::park() + 0xf0
0xfec88464    void ObjectMonitor::wait(long long,bool,Thread*) + 0x548
0xfe8cb974    void ObjectSynchronizer::wait(Handle,long long,Thread*) + 0x148
0xfe8cb508    JVM_MonitorWait + 0x29c
0xfc40e548    * java.lang.Object.wait(long) bci:0 (Interpreted frame)
0xfc40e4f4    * java.lang.Object.wait(long) bci:0 (Interpreted frame)
0xfc405a10    * java.lang.Object.wait() bci:2 line:485 (Interpreted frame)
... more lines removed here to reduce output...
----------------- t@12 -----------------
0xff2bfe3c    __lwp_park + 0x10
0xfe9925e4    AttachOperation*AttachListener::dequeue() + 0x148
0xfe99115c    void attach_listener_thread_entry(JavaThread*,Thread*) + 0x1fc
0xfec99ad8    void JavaThread::thread_main_inner() + 0x48
0xfec139f4    java_start + 0x118
0xff2bfd9c    _lwp_start
----------------- t@13 -----------------
0xff2c1500    _door_return + 0xc
----------------- t@14 -----------------
0xff2c1500    _door_return + 0xc

Frames that are prefixed with an asterisk (*) are Java frames, while frames that are not prefixed with an asterisk are native C/C++ frames.

The output of the utility can be piped through c++filt to demangle C++ mangled symbol names. Because the HotSpot VM is developed in the C++ language, the jstack utility prints C++ mangled symbol names for the HotSpot internal functions. The c++filt utility is delivered with the native C++ compiler suite: SUNWspro on Solaris OS and gnu on Linux.

The jstat Utility

The jstat utility uses the built-in instrumentation in the HotSpot VM to provide information on performance and resource consumption of running applications. The tool can be used when diagnosing performance issues, and in particular issues related to heap sizing and garbage collection. The jstat utility does not require the VM to be started with any special options. The built-in instrumentation in the HotSpot VM is enabled by default. The utility is included in the JDK download for all operating system platforms supported by Oracle, Inc.


Note:

The instrumentation is not accessible on Windows 98 or Windows ME. In addition, instrumentation is not accessible on Windows NT, 2000, or XP if a FAT32 file system is used.



The jstat Utility Options

-class

Specify this option to print statistics on the behavior of the class loader.

-compiler

Specify this option to print statistics of the behavior of the HotSpot compiler.

-gc

Specify this option to print statistics of the behavior of the garbage collected heap.

-gccapacity

Specify this option to print statistics of the capacities of the generations and their corresponding spaces.

-gccause

Specify this option to print the summary of garbage collection statistics (same as -gcutil), with the cause of the last and current (if applicable) garbage collection events.

-gcnew

Specify this option to print statistics of the behavior of the new generation.

-gcnewcapacity

Specify this option to print statistics of the sizes of the new generations and its corresponding spaces.

-gcold

Specify this option to print statistics of the behavior of the old and permanent generations.

-gcoldcapacity

Specify this option to print statistics of the sizes of the old generation.

-gcmetacapacity

Specify this option to print statistics of the sizes of the metaspace.

-gcutil

Specify this option to print a summary of garbage collection statistics.

-printcompilation

Specify this option to print HotSpot compilation method statistics.

For more information on the jstat utility, see the man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

The documentation includes a number of examples, and a few of those examples are repeated here in this document.

The jstat utility uses the virtual machine identifier (VMID) to identify the target process. The documentation describes the syntax of the VMID but its only required component is the local virtual machine identifier (LVMID) which is typically the operating system's PID for the target JVM process. Note that this is typical but may not always be the case.

The jstat tool provides data similar to the data provided by the tools vmstat and iostat on Solaris OS and Linux.

For a graphical representation of the data, you can use the visualgc tool. See "The visualgc Tool".

The jstat Utility Examples

Example 1Using the -gcutil option.

Below is an example of using the -gcutil option where the jstat utility attaches to LVMID number 2834, takes nine samples at 250 millisecond intervals, and displays the output.

$ jstat -gcutil 2834 250 7
  S0     S1     E      O      M     YGC     YGCT    FGC    FGCT     GCT   
  0.00  99.74  13.49   7.86  95.82      3    0.124     0    0.000    0.124
  0.00  99.74  13.49   7.86  95.82      3    0.124     0    0.000    0.124
  0.00  99.74  13.49   7.86  95.82      3    0.124     0    0.000    0.124
  0.00  99.74  13.49   7.86  95.82      3    0.124     0    0.000    0.124
  0.00  99.74  13.49   7.86  95.82      3    0.124     0    0.000    0.124
  0.00  99.74  13.49   7.86  95.82      3    0.124     0    0.000    0.124
  0.00  99.74  13.49   7.86  95.82      3    0.124     0    0.000    0.124

The output of this example shows that a young generation collection occurred between the third and fourth samples. The collection took 0.017 seconds and promoted objects from the eden space (E) to the old space (O), resulting in an increase of old space utilization from 46.56% to 54.60%.

Example 2Using the -gcnew option.

The following example illustrates the use of the -gcnew option where the jstat utility attaches to LVMID number 2834, takes samples at 250 millisecond intervals, and displays the output. In addition, it uses the -h3 option to display the column headers after every 3 lines of data.

$ jstat -gcnew -h3 2834 250
S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
 192.0  192.0    0.0    0.0 15  15   96.0   1984.0    942.0    218    1.999
 192.0  192.0    0.0    0.0 15  15   96.0   1984.0   1024.8    218    1.999
 192.0  192.0    0.0    0.0 15  15   96.0   1984.0   1068.1    218    1.999
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
 192.0  192.0    0.0    0.0 15  15   96.0   1984.0   1109.0    218    1.999
 192.0  192.0    0.0  103.2  1  15   96.0   1984.0      0.0    219    2.019
 192.0  192.0    0.0  103.2  1  15   96.0   1984.0     71.6    219    2.019
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
 192.0  192.0    0.0  103.2  1  15   96.0   1984.0     73.7    219    2.019
 192.0  192.0    0.0  103.2  1  15   96.0   1984.0     78.0    219    2.019
 192.0  192.0    0.0  103.2  1  15   96.0   1984.0    116.1    219    2.019

In addition to showing the repeating header string, this example shows that between the fourth and fifth samples, a young generation collection occurred, whose duration was 0.02 seconds. The collection found enough live data that the survivor space 1 utilization (S1U) would have exceeded the desired survivor size (DSS). As a result, objects were promoted to the old generation (not visible in this output), and the tenuring threshold (TT) was lowered from 15 to 1.

Example 3Using the -gcoldcapacity option.

The following example illustrates the use of the -gcoldcapacity option where the jstat utility attaches to LVMID number 21891 and takes three samples at 250 millisecond intervals. The -t option is used to generate a time stamp for each sample in the first column.

$ jstat -gcoldcapacity -t 21891 250 3
Timestamp    OGCMN     OGCMX       OGC        OC   YGC   FGC     FGCT     GCT
    150.1   1408.0   60544.0   11696.0   11696.0   194    80    2.874   3.799
    150.4   1408.0   60544.0   13820.0   13820.0   194    81    2.938   3.863
    150.7   1408.0   60544.0   13820.0   13820.0   194    81    2.938   3.863

The Timestamp column reports the elapsed time in seconds since the start of the target JVM. In addition, the -gcoldcapacity output shows the old generation capacity (OGC) and the old space capacity (OC) increasing as the heap expands to meet allocation or promotion demands. The OGC has grown from 11696 KB to 13820 KB after the 81st full generation capacity (FGC). The maximum capacity of the generation (and space) is 60544 KB (OGCMX), so it still has room to expand.

The jstatd Daemon

The jstatd daemon is an RMI server application that monitors the creation and termination of instrumented Java HotSpot VMs and provides an interface to allow remote monitoring tools to attach to JVMs running on the local host. For example, this daemon allows the jps utility to list processes on a remote system.


Note:

The instrumentation is not accessible on Windows 98 or Windows ME. In addition, instrumentation is not accessible on Windows NT, 2000, or XP if a FAT32 file system is used.


For more information about the jstatd daemon, including detailed usage examples, see the man page at

http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstatd.html

The visualgc Tool

The visualgc tool is related to the jstat tool (see "The jstat Utility"). The visualgc tool provides a graphical view of the garbage collection (GC) system. As with jstat, it uses the built-in instrumentation of the HotSpot VM.

The visualgc tool is not included in the JDK release but is available as a separate download from the jvmstat 3.0 web site at

http://www.oracle.com/technetwork/java/jvmstat-142257.html

The following screenshot output demonstrates how the GC and heap are visualized.

Figure 2-2 Sample Output from visualgc

Description of Figure 2-2 follows
Description of "Figure 2-2 Sample Output from visualgc"

Control+Break Handler

On Solaris OS or Linux, the combination of pressing the Control key and the backslash (\) key at the application console (standard input) causes the HotSpot VM to print a thread dump to the application's standard output. On Windows the equivalent key sequence is the Control and Break keys. The general term for these key combinations is the Control+Break handler.

On Solaris OS and Linux, a thread dump is printed if the Java process receives a QUIT signal. Therefore, the kill -QUIT pid command causes the process with the ID pid to print a thread dump to standard output.

The following sections describe the data printed by the Control+Break handler:

Thread Dump

The thread dump consists of the thread stack, including thread state, for all Java threads in the virtual machine. The thread dump does not terminate the application: it continues after the thread information is printed.

The following example illustrates a thread dump.

Full thread dump Java HotSpot(TM) Client VM (1.6.0-rc-b100 mixed mode):

"DestroyJavaVM" prio=10 tid=0x00030400 nid=0x2 waiting on condition [0x00000000..0xfe77fbf0]
   java.lang.Thread.State: RUNNABLE

"Thread2" prio=10 tid=0x000d7c00 nid=0xb waiting for monitor entry [0xf36ff000..0xf36ff8c0]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at Deadlock$DeadlockMakerThread.run(Deadlock.java:32)
        - waiting to lock <0xf819a938> (a java.lang.String)
        - locked <0xf819a970> (a java.lang.String)

"Thread1" prio=10 tid=0x000d6c00 nid=0xa waiting for monitor entry [0xf37ff000..0xf37ffbc0]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at Deadlock$DeadlockMakerThread.run(Deadlock.java:32)
        - waiting to lock <0xf819a970> (a java.lang.String)
        - locked <0xf819a938> (a java.lang.String)

"Low Memory Detector" daemon prio=10 tid=0x000c7800 nid=0x8 runnable [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"CompilerThread0" daemon prio=10 tid=0x000c5400 nid=0x7 waiting on condition [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x000c4400 nid=0x6 waiting on condition [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x000b2800 nid=0x5 in Object.wait() [0xf3f7f000..0xf3f7f9c0]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0xf4000b40> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
        - locked <0xf4000b40> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10 tid=0x000ae000 nid=0x4 in Object.wait() [0xfe57f000..0xfe57f940]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0xf4000a40> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:485)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
        - locked <0xf4000a40> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0x000ab000 nid=0x3 runnable 

"VM Periodic Task Thread" prio=10 tid=0x000c8c00 nid=0x9 waiting on condition 

The output consists of a number of thread entries separated by an empty line. The Java threads (threads that are capable of executing Java language code) are printed first, and these are followed by information on VM internal threads. Each thread entry consists of a header line followed by the thread stack trace.

The header line contains the following information about the thread:

  • Thread name

  • Indication if the thread is a daemon thread

  • Thread priority (prio)

  • Thread ID (tid), which is the address of a thread structure in memory

  • ID of the native thread (nid)

  • Thread state, which indicates what the thread was doing at the time of the thread dump (see table below)

  • Address range, which gives an estimate of the valid stack region for the thread

The following table lists the possible thread states that can be printed.

Table 2-1 Thread States

Thread State Description

NEW

The thread has not yet started

RUNNABLE

The thread is executing in the JVM

BLOCKED

The thread is blocked waiting for a monitor lock

WAITING

The thread is waiting indefinitely for another thread to perform a particular action

TIMED_WAITING

The thread is waiting for another thread to perform an action for up to a specified waiting time

TERMINATED

The thread has exited


Detected Deadlocks

In addition to the thread stacks, the Control+Break handler executes a deadlock detection algorithm. If any deadlocks are detected, it prints additional information after the thread dump on each deadlocked thread.

Found one Java-level deadlock:
=============================
"Thread2":
  waiting to lock monitor 0x000af330 (object 0xf819a938, a java.lang.String),
  which is held by "Thread1"
"Thread1":
  waiting to lock monitor 0x000af398 (object 0xf819a970, a java.lang.String),
  which is held by "Thread2"

Java stack information for the threads listed above:
===================================================
"Thread2":
        at Deadlock$DeadlockMakerThread.run(Deadlock.java:32)
        - waiting to lock <0xf819a938> (a java.lang.String)
        - locked <0xf819a970> (a java.lang.String)
"Thread1":
        at Deadlock$DeadlockMakerThread.run(Deadlock.java:32)
        - waiting to lock <0xf819a970> (a java.lang.String)
        - locked <0xf819a938> (a java.lang.String)

Found 1 deadlock.

If the Java VM flag -XX:+PrintConcurrentLocks is set, Control+Break will also print the list of concurrent locks owned by each thread.

Heap Summary

Starting with JDK 7, the Control+Break handler also prints a heap summary. This output shows the different generations (areas of the heap), with the size, the amount used, and the address range. The address range is especially useful if you are also examining the process with tools such as pmap.

Heap
 def new generation   total 1152K, used 435K [0x22960000, 0x22a90000, 0x22e40000
)
  eden space 1088K,  40% used [0x22960000, 0x229ccd40, 0x22a70000)
  from space 64K,   0% used [0x22a70000, 0x22a70000, 0x22a80000)
  to   space 64K,   0% used [0x22a80000, 0x22a80000, 0x22a90000)
 tenured generation   total 13728K, used 6971K [0x22e40000, 0x23ba8000, 0x269600
00)
   the space 13728K,  50% used [0x22e40000, 0x2350ecb0, 0x2350ee00, 0x23ba8000)
 compacting perm gen  total 12288K, used 1417K [0x26960000, 0x27560000, 0x2a9600
00)
   the space 12288K,  11% used [0x26960000, 0x26ac24f8, 0x26ac2600, 0x27560000)
    ro space 8192K,  62% used [0x2a960000, 0x2ae5ba98, 0x2ae5bc00, 0x2b160000)
    rw space 12288K,  52% used [0x2b160000, 0x2b79e410, 0x2b79e600, 0x2bd60000)

If the Java VM flag -XX:+PrintClassHistogram is set, then the Control+Break handler will produce a heap histogram.

Native Operating System Tools

This section lists a number of native tools available on Windows, Linux, and Solaris OS that are useful for troubleshooting or monitoring purposes. A brief description is provided for each tool. For further details, refer to the operating system documentation (or man pages in the case of Solaris OS and Linux).

The section also contains information on some tools introduced or improved in Solaris OS version 10.

Table 2-2 Native Troubleshooting Tools on Windows

Tool Description

dumpchk

Command-line utility to verify that a memory dump file has been created correctly This tool is included in the Debugging Tools for Windows download available from the Microsoft web site (see "Collecting Crash Dumps on Windows".

msdev debugger

Command-line utility that can be used to launch Visual C++ and the Win32 debugger.

userdump

The User Mode Process Dumper is included in the OEM Support Tools download available from the Microsoft web site (see "Collecting Crash Dumps on Windows").

windbg

Windows debugger which can be used to debug Windows applications or crash dumps. This tool is included in the Debugging Tools for Windows download available from the Microsoft web site (see "Collecting Crash Dumps on Windows").

/Md and /Mdd compiler options

Compiler options that automatically include extra support for tracking memory allocations.


You can also search for Windows-specific debug support on MSDN at

http://msdn.microsoft.com

The table below lists troubleshooting tools available on Linux.

Table 2-3 Native Troubleshooting Tools on Linux

Tool Description

c++filt

Demangle C++ mangled symbol names. This utility is delivered with the native C++ compiler suite: gcc on Linux.

gdb

GNU debugger.

libnjamd

Memory allocation tracking.

lsstack

Print thread stack (similar to pstack in Solaris OS).

Not all distributions provide this tool by default; therefore, you might have to download it from www.sourceforge.net.

ltrace

Library call tracer (equivalent to truss -u in Solaris OS).

Not all distributions provide this tool by default; therefore, you might have to download it from www.sourceforge.net.

mtrace and muntrace

GNU malloc tracer.

proc tools such as pmap and pstack

Some, but not all, of the proc tools on Solaris OS have equivalent tools on Linux. In addition, core file support is not as good as for Solaris OS; for example, pstack does not work for core dumps.

strace

System call tracer (equivalent to truss -t in Solaris OS).

top

Display most CPU-intensive processes.

vmstat

Report information about processes, memory, paging, block I/O, traps, and CPU activity.


The table below lists troubleshooting tools available on Solaris OS.

Table 2-4 Native Troubleshooting Tools on Solaris OS

Tool Description

coreadm

Specify name and location of core files produced by the Java VM.

cpustat

Monitor system behavior using CPU performance counters.

cputrack

Monitor process and LWP behavior using CPU performance counters.

c++filt

Demangle C++ mangled symbol names. This utility is delivered with the native C++ compiler suite: SUNWspro on Solaris OS.

dtrace

Introduced in Solaris 10 OS, DTrace is a dynamic tracing compiler and tracing utility. It can perform dynamic tracing of kernel functions, system calls, and user functions. This tool allows arbitrary, safe scripting to be executed at entry, exit, and other probe points. The script is written in C-like but safe pointer semantics language called the D programming language. See also "Using the DTrace Tool".

gcore

Force a core dump of a process. The process continues after the core dump is written.

intrstat

Report statistics on CPU consumed by interrupt threads.

iostat

Report I/O statistics.

libumem

Introduced in Solaris 9 OS update 3, this library provides fast, scalable object-caching memory allocation and extensive debugging support. The tool can be used to find and fix memory management bugs (see "Using the libumem Tool to Find Leaks").

mdb

Modular debugger for kernel and user applications and crash dumps

netstat

Display the contents of various network-related data structures.

pargs

Print process arguments, environment variables, or auxiliary vector. Long output is not truncated as it would be by other commands, such as ps.

pfiles

Print information on process file descriptors. Starting with Solaris 10 OS, the tool prints the filename also.

pldd

Print shared objects loaded by a process.

pmap

Print memory layout of a process or core file, including heap, data, text sections. Starting with Solaris 10 OS, stack segments are clearly identified with the text [stack] along with the thread ID. See also "Improvements in the pmap Tool".

prstat

Report statistics for active Solaris OS processes. (Similar to top).

prun

Set the process to running mode (reverse of pstop).

ps

List all processes.

psig

List the signal handlers of a process.

pstack

Print stack of threads of a given process or core file. Starting with Solaris 10 OS, Java method names can be printed for Java frames. See also "Improvements in the pstack Tool".

pstop

Stop the process (suspend).

ptree

Print process tree containing the given PID.

sar

System activity reporter.

sdtprocess

Display most CPU-intensive processes. (Similar to top).

sdtperfmeter

Display graphs showing system performance, for example, CPU, disks, network, and so forth.

top

Display most CPU-intensive processes. This tool is available as freeware for Solaris OS but is not installed by default.

trapstat

Display runtime trap statistics. (SPARC only)

truss

Trace entry and exit events for system calls, user-mode functions, and signals; optionally stop the process at one of these events. This tool also prints the arguments of system calls and user functions.

vmstat

Report system virtual memory statistics.

watchmalloc

Track memory allocations.


Using the DTrace Tool

Solaris 10 OS includes the DTrace tool, which allows dynamic tracing of the operating system kernel and user-level programs. This tool supports scripting at system-call entry and exit, at user-mode function entry and exit, and at many other probe points. The scripts are written in the D programming language, which is a C-like language with safe pointer semantics. These scripts can help you in troubleshooting problems or solving performance issues.

The dtrace command is a generic front-end to the DTrace tool. This command provides a simple interface to invoke the D language, to retrieve buffered trace data, and to access a set of basic routines to format and print traced data.

You may write your own customized DTrace scripts, using the D language, or download and use one or more of the many scripts that are already available on various sites.

The probes are delivered and instrumented by kernel modules called providers. The types of tracing offered by the probe providers include user instruction tracing, function boundary tracing, kernel lock instrumentation, profile interrupt, system call tracing, and much more. If you write your own scripts, you use the D language to enable the probes; this language also allows conditional tracing and output formatting.

You can use the dtrace -l command to explore the set of providers and probes that are available on your Solaris OS.

The DTraceToolkit is a collection of useful documented scripts developed by the OpenSolaris DTrace community. For more information on the DTraceToolkit, see the DTraceToolkit web page at

http://www.opensolaris.org/os/community/dtrace/dtracetoolkit/

For more information on dynamic tracing in general, see the Solaris Dynamic Tracing Guide at

http://docs.oracle.com/cd/E19253-01/817-6223/

Probe Providers in Java HotSpot VM

Starting with JDK 7, the Java HotSpot VM contains two built-in probe providers: hotspot and hotspot_jni. These providers deliver probes that can be used to monitor the internal state and activities of the VM, as well as the Java application that is running.

The JVM probe providers can be categorized as follows:

  • VM lifecycle: VM initialization begin and end, and VM shutdown.

  • Thread lifecycle: thread start and stop, thread name, thread ID, and so on.

  • Class-loading: Java class loading and unloading.

  • Garbage collection: start and stop of garbage collection, system-wide or by memory pool.

  • Method compilation: method compilation begin and end, and method loading and unloading.

  • Monitor probes: wait events, notification events, contended monitor entry and exit.

  • Application tracking: method entry and return, allocation of a Java object.

In order to call from native code to Java code, the native code must make a call through the JNI interface. The hotspot_jni provider manages DTrace probes at the entry point and return point for each of the methods that the JNI interface provides for invoking Java code and examining the state of the VM.

Example 2-1 Example of Using DTrace

At probe points, you can print the stack trace current thread using the ustack built-in function. This function prints Java method names in addition to C/C++ native function names. The following is a simple D script that prints a full stack trace whenever a thread calls the read system call:

#!/usr/sbin/dtrace -s
syscall::read:entry 
/pid == $1 && tid == 1/ {    
   ustack(50, 0x2000);
}

The above script is stored in a file named read.d and is run by specifying the PID of the Java process that is traced.

read.d pid

If your Java application generated a lot of I/O or had some unexpected latency, the use of the DTrace tool and its ustack() action can help you diagnose the problem.

Improvements in the pmap Tool

The pmap utility was improved in Solaris 10 OS to print stack segments with the text [stack]. This text helps you to locate the stack easily.

The following example shows the output from this tool:

19846:    /net/myserver/export1/user/j2sdk6/bin/java -Djava.endorsed.d
00010000      72K r-x--  /export/disk09/jdk/6/rc/b63/binaries/solsparc/bin/java
00030000      16K rwx--  /export/disk09/jdk/6/rc/b63/binaries/solsparc/bin/java
00034000   32544K rwx--    [ heap ]
D1378000      32K rwx-R    [ stack tid=44 ]
D1478000      32K rwx-R    [ stack tid=43 ]
D1578000      32K rwx-R    [ stack tid=42 ]
D1678000      32K rwx-R    [ stack tid=41 ]
D1778000      32K rwx-R    [ stack tid=40 ]
D1878000      32K rwx-R    [ stack tid=39 ]
D1974000      48K rwx-R    [ stack tid=38 ]
D1A78000      32K rwx-R    [ stack tid=37 ]
D1B78000      32K rwx-R    [ stack tid=36 ]
[.. more lines removed here to reduce output ..]
FF370000       8K r-x--  /usr/lib/libsched.so.1
FF380000       8K r-x--  /platform/sun4u-us3/lib/libc_psr.so.1
FF390000      16K r-x--  /lib/libthread.so.1
FF3A4000       8K rwx--  /lib/libthread.so.1
FF3B0000       8K r-x--  /lib/libdl.so.1
FF3C0000     168K r-x--  /lib/ld.so.1
FF3F8000       8K rwx--  /lib/ld.so.1
FF3FA000       8K rwx--  /lib/ld.so.1
FFB80000      24K -----    [ anon ]
FFBF0000      64K rwx--    [ stack ]
 total    167224K

Improvements in the pstack Tool

Prior to Solaris 10 OS, the pstack utility did not support Java. It printed hexadecimal addresses for both interpreted and compiled Java methods.

Starting from Solaris 10 OS, the pstack command-line tool prints mixed mode stack traces (Java and C/C++ frames) from a core file or a live process. The tool prints Java method names for interpreted, compiled and inlined Java methods.

Custom Diagnostic Tools

The JDK has extensive APIs for developing custom tools to observe, monitor, profile, debug, and diagnose issues in applications that are deployed in the JRE. The development of new tools is beyond the scope of this document. Instead this section provides a brief overview of the APIs available.

All the packages mentioned below are fully described in the Java SE API specification at

http://docs.oracle.com/javase/8/docs/api/index.html

Refer also to example and demonstration code that is included in the JDK download.

The java.lang.management Package

The java.lang.management package provides the management interface for monitoring and management of the JVM and the OS. Specifically it covers interfaces for the following systems:

  • Class loading

  • Compilation

  • Garbage collection

  • Memory manager

  • Runtime

  • Threads

The JDK release includes example code that demonstrates the usage of the java.lang.management package. These examples can be found in the $JAVA_HOME/demo/management directory. Some of these examples are as follows:

  • MemoryMonitor demonstrates the use of the java.lang.management API to observe the memory usage of all memory pools consumed by the application.

  • FullThreadDump demonstrates the use of the java.lang.management API to get a full thread dump and detect deadlocks programmatically.

  • VerboseGC demonstrates the use of the java.lang.management API to print the garbage collection statistics and memory usage of an application.

In addition to the java.lang.management package, the JDK release includes platform extensions in the com.sun.management package. The platform extensions include a management interface to obtain detailed statistics from garbage collectors that perform collections in cycles. These extensions also include a management interface to obtain additional memory statistics from the operating system.

For more information on the platform extensions, see the Java SE Monitoring and Management documentation at

http://docs.oracle.com/javase/8/docs/technotes/guides/management/index.html

The java.lang.instrument Package

The java.lang.instrument package provides services that allow Java programming language agents to instrument programs running on the Java VM. Instrumentation is used by tools such as profilers, tools for tracing method calls, and many others. The package facilitates both load-time and dynamic instrumentation. It also includes methods to obtain information on the loaded classes and information about the amount of storage consumed by a given object.

The java.lang.Thread Class

The java.lang.Thread class has a static method called getAllStackTraces, which returns a map of stack traces for all live threads. The Thread class also has a method called getState, which returns the thread state; states are defined by the java.lang.Thread.State enumeration. These methods can be useful when adding diagnostic or monitoring capabilities to an application.

Java Virtual Machine Tools Interface

The JVM Tools Interface (JVM TI) is a native (C/C++) programming interface that can be used to develop a wide range of developing and monitoring tools. JVM TI provides an interface for the full breadth of tools that need access to VM state, including but not limited to profiling, debugging, monitoring, thread analysis, and coverage analysis tools.

Some examples of agents that rely on JVM TI are the following:

  • HPROF

  • Java Debug Wire Protocol (JDWP)

  • The java.lang.instrument package

The specification for JVM TI can be found in the JVM Tool Interface documentation at

http://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html

The JDK release includes example code that demonstrates the usage of JVM TI. These examples can be found in the $JAVA_HOME/demo/jvmti directory. Some of the examples are as follows:

Java Platform Debugger Architecture

The Java Platform Debugger Architecture (JPDA) is the architecture designed for use by debuggers and debugger-like tools. It consists of two programming interfaces and a wire protocol.

A complete description (including specifications) for JPDA is located in the Java Platform Debugger Architecture documentation at

http://docs.oracle.com/javase/8/docs/technotes/guides/jpda/index.html

The jdb utility is included in the JDK release as the example command-line debugger. The jdb utility uses the JDI to launch or connect to the target VM. For more information on the jdb utility, see "The jdb Utility".

In addition to traditional debugger-type tools, JDI can also be used to develop tools that help in post-mortem diagnostics and scenarios where the tool needs to attach to a process in a non-cooperative manner (for example, a hung process).

Contents    Previous    Next

Oracle and/or its affiliates Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.
Contact Us