Today I learned something new, courtesy of an interview question from a prominent tech company. If you ever wanted to know how to get stack traces for all threads and summary information of a running JVM under Linux, you can do it with nothing but the familiar kill command. By sending the QUIT signal to the JVM process, it will print information like the following to the console:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ java Looper & | |
$ kill -QUIT %1 | |
2014-10-23 20:35:55 | |
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.72-b04 mixed mode): | |
"Service Thread" daemon prio=10 tid=0x00007f28680a0800 nid=0xe69 runnable [0x0000000000000000] | |
java.lang.Thread.State: RUNNABLE | |
"C2 CompilerThread1" daemon prio=10 tid=0x00007f286809e000 nid=0xe68 waiting on condition [0x0000000000000000] | |
java.lang.Thread.State: RUNNABLE | |
"C2 CompilerThread0" daemon prio=10 tid=0x00007f286809b800 nid=0xe67 waiting on condition [0x0000000000000000] | |
java.lang.Thread.State: RUNNABLE | |
"Signal Dispatcher" daemon prio=10 tid=0x00007f2868099000 nid=0xe66 waiting on condition [0x0000000000000000] | |
java.lang.Thread.State: RUNNABLE | |
"Finalizer" daemon prio=10 tid=0x00007f286806f800 nid=0xe65 in Object.wait() [0x00007f286c425000] | |
java.lang.Thread.State: WAITING (on object monitor) | |
at java.lang.Object.wait(Native Method) | |
- waiting on <0x00000000d77047f8> (a java.lang.ref.ReferenceQueue$Lock) | |
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135) | |
- locked <0x00000000d77047f8> (a java.lang.ref.ReferenceQueue$Lock) | |
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151) | |
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) | |
"Reference Handler" daemon prio=10 tid=0x00007f286806d800 nid=0xe64 in Object.wait() [0x00007f286c526000] | |
java.lang.Thread.State: WAITING (on object monitor) | |
at java.lang.Object.wait(Native Method) | |
- waiting on <0x00000000d7704410> (a java.lang.ref.Reference$Lock) | |
at java.lang.Object.wait(Object.java:503) | |
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133) | |
- locked <0x00000000d7704410> (a java.lang.ref.Reference$Lock) | |
"main" prio=10 tid=0x00007f2868009800 nid=0xe5e waiting on condition [0x00007f28715bf000] | |
java.lang.Thread.State: TIMED_WAITING (sleeping) | |
at java.lang.Thread.sleep(Native Method) | |
at Looper.main(Looper.java:4) | |
"VM Thread" prio=10 tid=0x00007f2868069800 nid=0xe63 runnable | |
"GC task thread#0 (ParallelGC)" prio=10 tid=0x00007f286801f800 nid=0xe5f runnable | |
"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f2868021800 nid=0xe60 runnable | |
"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007f2868023000 nid=0xe61 runnable | |
"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007f2868025000 nid=0xe62 runnable | |
"VM Periodic Task Thread" prio=10 tid=0x00007f28680ab800 nid=0xe6a waiting on condition | |
JNI global references: 106 | |
Heap | |
PSYoungGen total 36352K, used 1249K [0x00000000d7700000, 0x00000000d9f80000, 0x0000000100000000) | |
eden space 31232K, 4% used [0x00000000d7700000,0x00000000d7838608,0x00000000d9580000) | |
from space 5120K, 0% used [0x00000000d9a80000,0x00000000d9a80000,0x00000000d9f80000) | |
to space 5120K, 0% used [0x00000000d9580000,0x00000000d9580000,0x00000000d9a80000) | |
ParOldGen total 82944K, used 0K [0x0000000086600000, 0x000000008b700000, 0x00000000d7700000) | |
object space 82944K, 0% used [0x0000000086600000,0x0000000086600000,0x000000008b700000) | |
PSPermGen total 21504K, used 2422K [0x0000000081400000, 0x0000000082900000, 0x0000000086600000) | |
object space 21504K, 11% used [0x0000000081400000,0x000000008165dbf8,0x0000000082900000) |