A thread dump is a collection of active threads running on JVM. In other words, it is snapshot of current state of all the Java threads running on JVM. The threads could be either invoked by your own application or that is managed by the JVM itself. But, all the threads will be captured and stored when you instruct JVM to get the thread dump.
Thread dumps are very helpful when your application has performance issue, by taking the thread dumps, you will be able to analyze if there is any deadlock between two threads or there is insufficient memory to execute all the threads. Deadlocks bring some or all of an application to a complete halt.
It is very simple to take the thread dumps from running JVM. There are several ways to take the thread dump from JVM. It is highly recommended to take more than 1 thread dump. A good practice is to take 5 to 10 thread dumps at a regular interval (eg. 1 thread dump every 10 seconds). This is because, taking multiple thread dumps helps you to see the different state of each thread for certain duration and get more knowledge on each thread activities.
How to take thread dumps in Windows?
If you are running your server in Windows, then use the following command to take the thread dumps:
CTRL + BREAK (or) CTRL + Fn + PAUSE (or) CTRL + ALT + ESC
Sometimes you may not find the right keys in your system to initiate the command, so I have listed some of the possible combinations of keys that are used for taking the thread dumps in Windows operating system.
If you are trying to take the thread dump from Tomcat server when it is running on the command prompt, then directly press the above keys in the command prompt, it will display the details of thread dumps. You just have to copy the information and paste it into a text document for the further analysis. The process of taking the thread dumps could be different for each servers.
Here is a example thread dumps I have taken from the tomcat server:
- locked <0x29a002f8> (a [Lorg.apache.catalina.Service;) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) - locked <0x29907fb0> (a org.apache.catalina.core.StandardServer) at org.apache.catalina.startup.Catalina.start(Catalina.java:689) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces sorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:321) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455) "VM Thread" prio=10 tid=0x01927000 nid=0x32cc runnable "VM Periodic Task Thread" prio=10 tid=0x0194ec00 nid=0x20e4 waiting on condition JNI global references: 170 Heap def new generation total 9792K, used 8850K [0x242f0000, 0x24d80000, 0x2984000 0) eden space 8768K, 89% used [0x242f0000, 0x24aa1ff8, 0x24b80000) from space 1024K, 94% used [0x24b80000, 0x24c72b20, 0x24c80000) to space 1024K, 0% used [0x24c80000, 0x24c80000, 0x24d80000) tenured generation total 21588K, used 13680K [0x29840000, 0x2ad55000, 0x342f0 000) the space 21588K, 63% used [0x29840000, 0x2a59c128, 0x2a59c200, 0x2ad55000) compacting perm gen total 12288K, used 5865K [0x342f0000, 0x34ef0000, 0x382f00 00) the space 12288K, 47% used [0x342f0000, 0x348aa410, 0x348aa600, 0x34ef0000) ro space 10240K, 45% used [0x382f0000, 0x38771888, 0x38771a00, 0x38cf0000) rw space 12288K, 54% used [0x38cf0000, 0x393704f8, 0x39370600, 0x398f0000) Feb 16, 2016 5:04:10 PM org.apache.catalina.util.SessionIdGenerator createSecure Random INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRN G] took [185] milliseconds. Feb 16, 2016 5:04:11 PM org.apache.catalina.startup.HostConfig deployWAR INFO: Deploying web application archive
How to take thread dumps in Unix/Linux?
Run the following command to take the thread dump in Unix or Linux machines:
Kill –3 process_id
You can use the following command to get the process id for Java:
ps -ef | grep java
When you run the above command, the thread dump will be sent to where ever the standard output is redirected to.
(In tomcat server, by default the thread dump will be sent to TOMCAT_HOME/logs/Catalina.out). QUIT command signal does not actually kill the java process. The thread dump will be sent to the standard output and the process will continue running.
How thread dump request works internally?
When you are invoking the command to request the JVM to send the thread dump, the following steps occurs inside JVM,
- The Java process will be paused and all the threads currently running will be halted immediately.
- The main Java thread will request all the threads to provide details of what they are doing at the moment.
- The thread dump will be sent to standard output either it is a log file or console to print the details.
- The Java process will continue the job and all the threads will resume their work.
- This task takes only few seconds to accomplish and then resume where they left off.
I hope this tutorial helped you to understand the thread dumps in Java and how to get them using commands in Windows / Unix / Linux operating systems. If you have any questions, please write it in the comments section.