Inspecting Java threads in Linux using top
You can inspect java threads with the tool jstack
. It will list the names, stacktraces and other useful information of all threads belonging to the specified process pid.
Edit: The parameter nid in the thread dump of jstack is the hex version of the LWP that is displayed by top in the pid column for threads.
This might be a little old, but here's what I did to kinda merge top and jstack together. I used two scripts, but I'm sure it all could be done in one.
First, I save the output of top with the pids for my java threads into a file and save the jstack output into another file:
#!/bin/shtop -H -b -n 1 | grep java > /tmp/top.logjstack -l `ps fax | grep java | grep tomcat | sed "s/ *\([0-9]*\) .*/\1/g"` > /tmp/jstack.log
Then I use a perl script to call the bash script (called cpu-java.sh here) and kinda merge the two files (/tmp/top.log and /tmp/jstack.log):
#!/usr/bin/perlsystem("sh cpu-java.sh");open LOG, "/tmp/top.log" or die $!;print "PID\tCPU\tMem\tJStack Info\n";while ($l = <LOG>) { $pid = $l; $pid =~ s/root.*//g; $pid =~ s/ *//g; $hex_pid = sprintf("%#x", $pid); @values = split(/\s{2,}/, $l); $pct = $values[4]; $mem = $values[5]; open JSTACK, "/tmp/jstack.log" or die $!; while ($j = <JSTACK>){ if ($j =~ /.*nid=.*/){ if ($j =~ /.*$hex_pid.*/){ $j =~ s/\n//; $pid =~ s/\n//; print $pid . "\t" . $pct . "\t" . $mem . "\t" . $j . "\n"; } } } close JSTACK;}close LOG;
The output helps me to find out which threads are hogging my cpu:
PID CPU Mem JStack Info22460 0 8.0 "main" prio=10 tid=0x083cb800 nid=0x57bc runnable [0xb6acc000]22461 0 8.0 "GC task thread#0 (ParallelGC)" prio=10 tid=0x083d2c00 nid=0x57bd runnable 22462 0 8.0 "GC task thread#1 (ParallelGC)" prio=10 tid=0x083d4000 nid=0x57be runnable 22463 0 8.0 "GC task thread#2 (ParallelGC)" prio=10 tid=0x083d5800 nid=0x57bf runnable 22464 0 8.0 "GC task thread#3 (ParallelGC)" prio=10 tid=0x083d7000 nid=0x57c0 runnable...
Then I can go back to /tmp/jstack.log and take a look at the stack trace for the problematic thread and try to figure out what's going on from there. Of course this solution is platform-dependent, but it should work with most flavors of *nix and some tweaking here and there.
I have created a top-like command specifically for visualizing Java threads ordered by CPU usage and posted the source code at: https://github.com/jasta/jprocps. The command-line syntax is not nearly as rich as top, but it does support some of the same commands:
$ jtop -n 1
Sample output (showing ant and IntelliJ running):
PID TID USER %CPU %MEM THREAD13480 13483 jasta 104 2.3 main13480 13497 jasta 86.3 2.3 C2 CompilerThread113480 13496 jasta 83.0 2.3 C2 CompilerThread0 4866 4953 jasta 1.0 13.4 AWT-EventQueue-1 12.1.4#IC-129.713, eap:false 4866 14154 jasta 0.9 13.4 ApplicationImpl pooled thread 36 4866 5219 jasta 0.8 13.4 JobScheduler pool 5/8
From this output, I can pull up the thread's stack trace in jconsole
or jstack
manually and figure out what's going on.
NOTE: jtop
is written in Python and requires that jstack
be installed.