Cool JDK tools you probably never used

Cool JDK tools you probably never used

Lets say you have some remote server running Java. How would you see what is happening with JVM? Connecting profiler remotely requires open ports and definitely won’t be quick. Running profiler on the remote server is not usually possible since the servers rarely have X11 installed. In this case a bunch of tools from JDK may help you.

These include:

  • jps
  • jstat
  • jinfo
  • jstack
  • jmap
  • jhat

Let’s have a look at what these tools can do.


This tool displays all of the JVM running on your host

jps -v

13397 Jps -Dapplication.home=/data/Tools/jdk1.6.0_26 -Xms8m
11170 smartsvn.jar -XX:-UseSSE42Intrinsics …
9762 Main -Djdk.home=/data/Tools/jdk1.6.0_26 -Dnetbeans.system_http_proxy=…


This tool displays JVM information mostly about memory

jstat -gcutil 9762

0.00 6.03 41.22 72.27 75.29 57 6.608 6 4.599 11.206

This example shows various data on garbage collection.


Perfect tool to see general information on JVM

jinfo 9762

Attaching to process ID 9762, please wait…
Debugger attached successfully.
Server compiler detected.
JVM version is 20.1-b02
Java System Properties:

java.vendor = Sun Microsystems Inc.
netbeans.user = /home/andy/.netbeans/dev

plugin.manager.check.updates = false

VM Flags:

-Djdk.home=/data/Tools/jdk1.6.0_26 -Dnetbeans.system_http_proxy=DIRECT



Unbelievable tool to see all of the threads and stack of these threads. You can also dump you threads when you run JVM in foreground by pressing Ctrl+ in Linux terminal however usually it is not the case.

jstack 9762

Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.1-b02 mixed mode):

“Attach Listener” daemon prio=10 tid=0x00007f3be4003000 nid=0x35b6 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

“Inactive RequestProcessor thread [$DelegateChildren$2]” daemon prio=10 tid=0x00007f3bfc60f000 nid=0x35a9 in Object.wait() [0x00007f3bc3ffe000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.openide.util.RequestProcessor$
– locked <0x00000007e86a2940> (a java.lang.Object)

Newer versions of jstack can also try to detect deadlocks in your code.


Prints information on the shared libraries loaded by JVM. Can be useful if you use JNI.

jmap 9762

0x0000000040000000 49K /data/Tools/jdk1.6.0_26/bin/java
0x00000030e9200000 87K /lib64/
0x000000377f000000 42K /lib64/

But it’s also able to create a detailed JVM dump which can be viewed by jhat tool later. You can download this dump to your developer host.

jmap -dump:file=test.dmp 9762
Heap dump file created


It’s not just a tool, it’s a small server which parses the dump created by jmap and provides HTML interface to view dump data.

jhat test.dmp

It will show you lots of details on your objects and relations between them in various dimensions.

As you see there’s a bunch of interesting tools which will allow you to understand what’s happening with the remote JVM. Of course they are more complex in comparison to VisualVM or JProfiler but there are definitely some circumstances when these tools can be useful. And you don’t need to install anything additional since all these tools bundled with the JDK.