Tuesday, April 23, 2024

4 Ways to take Heap dump in Tomcat and Java and 3 Tools to Analyse .hprof files

The heap dump is a great source of information on identifying memory related issues on Java application e.g. web and application servers like Tomcat, WebLogic, JBoss, WebSphere and IDEs like IntelliJIDEA and Eclipse. When you take heap dump all live objects of heap with their count and other details are written into a huge file (the .hprof file) for analysis. The name and location of heap dump file is provided by command you use to take the heap dump. There are many command line tools in JDK e.g. jmap and jcmd which can be used to take the heap dump in Java. 

Though, most common way to take the heap dump is by using JVM command line argument -XX:+HeapDumpOnOutOfMemoryError, which instructs JVM to create heap dump when JVM dies due to java.lang.OutOfMemoryError

You might have seen several huge .hprof files in Tomcat bin directory, those are nothing but heap dumps of Tomcat dying due to java.lang.OutOfMemoryError in Java. 

I first come across heap dump due to a space issue in our application. The file system out application was using to run Tomcat server was almost filled up and I am searching from some huge files, usually greater than 1GB to remove. 

A quick run of find command with -size option shows me lots of .hprof file from last couple of months. That time, I didn't know that those java_pid4343.hprof files are heap dumps of Tomcat server but after a quick Google I understood that those are nothing but heap dump of Tomcat died in recent months due to OutOfMemoryError. 

In this article, I'll show you all three ways to take the heap dump in a Java application e.g. Tomcat, WebSphere, JBoss, WebLogic, Glassfish or any other web servers running on Windows or Linux environment. The process is exactly similar and should work for all Java application as we are only going to use the tools available in JDK. 

How to take Heap dump in Java? 

Here are the three most common ways to take the heap dump in Java application like Tomcat and WebLogic Server:

1) By using -XX:+HeapDumpOnOutOfMemoryError

The first and foremost rule is that you must have the JVM options -XX:+HeapDumpOnOutOfMemoryError configured as part of your JVM startups. It's also one of the 10 essential JVM options I recommend for any Java application. 

This JVM flag is a must for production systems as it is often the only way to analyze a crash or out of memory issues.  I have also included this in my earlier article about 10 essential JVM flags for Production

The heap dump will be generated in the "current directory" of the JVM by default. If you want to create heap dumps on specific location then you use the -XX:HeapDumpPath=[path-to-heap-dump-directory] flag to specify the location of your choice e.g. if you give -XX:HeapDumpPath=/local/dumps to your Tomcat then it will generate the heap dump on /local/dumps directory. 

I generally prefer not to give any specific location and let Tomcat dump the heap at default location which is the tomcat's bin directory. 

Though, you should remember that the heap dump file can be huge, up to Gigabytes, so ensure that the target file system has enough space. You can also refer Java Performance Companion 1st edition by Charlie Hunt to learn more about analyzing heap dump and thread dump in Java.

2) By using jVisualVM

The VisualVM GUI tool provides the easiest way to take and analyze the heap dump of a running Java process. If you are not familiar with jVisualVM or Visual VM, it's a good tool integrating several command like JDK tools and lightweight profiling capabilities. 

It is designed for both production and development time use, it further enhances the capability of monitoring and performance analysis for Java application. 

You can use this tool to take heap dump and thread dump of any Java process including Tomcat, because its runs on JVM. To learn more about Visual VM I suggest to take a look at these Java performance courses, which explains about this and various essentials tools for Java developers. 

In order to take a heap dump of Tomcat, just remotely connect the Tomcat with Visual VM and then choose the option to take heap dump as shown in following diagram:

4 Ways to take Heap dump in Tomcat and Java and Tools for Analysis


3) By using jmap command 

Though you can use GUI tools like VisualVM to generate heap dump of a running Java program, it's easier to generate the heap dump and thread dump from command line, which can be done by using the jmap command as shown below:

$ jmap -dump:live, file=/location/of/heap_dump.hprof PID

Where file specifies the name and location of heap dump file and PID is the process id of running Java application e.g. Tomcat Server

You can find the process id of Java application either by using ps -ef | grep "keyword" in Linux, where keyword uniquely search for your Java application, or you can use the jps command from the JDK to show process id of all Java application running in any machine. 

It's also worth noting that using live option in jmap will force a full GC to occur before the heap dump is created (If you are not familiar with jmap command, I suggest to read Java Performance The Definitive Guide By Scott Oaks, one of the best book to learn about essential Java tools).


4) By using jcmd command

Apart from jmap, you can also use the jcmd command to take the heap dump in Java 7 or Java 8. Yes, unlike jmap which is available in Java SE 6 also, the jcmd command line tool is only available from JDK 7 and 8 onwards like Java 17 or even Java 21. 

The jcmd tool is used to send diagnostic command requests to the JVM and can be used to take the heap dump of runnign Java application as shown in following example:

$ jcmd PID GC.heap_dump /path/to/tomcatheapdump.hprof

Here PID is the process id of Java application and GC.heap_dump instruct jcmd to dump the heap at the location given after it.

If you don't know the PID, you can use use the approach suggested earlier using ps command in Linux or jps, another java command line utility. Even jcmd without any parameters also list all JVM processes, starting with a PID. 

Unlike jmap, you don't need to tell jcmd to dump only live objects of heap into heap dump, that is the default behavior of jcmd utility. Though, for some reasons, if you want those dead objects (eligible for Garbage collection) to be included in heap dump, you can specify -all option at the end of jcmd command line. 

If you are not familiar with the jcmd command or wants to learn more about it, I suggest you to refer Java Performance Companion 1st edition by Charlie Hunt, the most up-to-date books on Java performance tuning and tools.

3 Tools to Analyze Heap dump (.hprof files) in Java

Once you get the heap dump in your file system (the .hprof file), you can use following tools to open and analyze the Java heap dump. 

1) jhat
2) jvisualvm
3) mat

1. jhat

This is one more command line tool which ships along with JDK and you can find in the JAVA_HOME/bin directory. This is actually the original heap analysis tool, it's full form itself is Java Heap Analysis Tool (jhat). 

It reads the heap dump and runs a small HTTP server that lets you look at the data through a series of web page links, as shown in following images. 

Like other tools, if you want to learn more about jhat, I suggest to take a look at any good book on Java performance listed here. 

2. jvisualvm

The VisualVM is a GUI tool which lets you to take heap dump and also analyze it to find the memory leak and retained memory issues. 

The monitor tab of jvisualvm can take a heap dump from an active Java application e.g. Tomcat server listening on port 8080. It can also load existing heap dump, the .hropf files, which tomcat produce when die due to OutOfMemoryError in the TOMCAT_HOME/bin directory. 

Once loaded, you can browse through heap dump to find the largest retained objects and executing arbitrary queries against the heap. See Java Performance Companion by Charlie Hunt, Monica Beckwith, Poonam Parhar, and Bengt Rutisson to learn more about jvisualvm tool. 



3. MAT

The MAT tool, also known as Eclipse Memory Analyzer Tool (MAT) can load one or more heap dumps and analyze them. You can use this tool to generate useful pie charts showing which objects has occupied the largest amount of heap and spot any memory leak i.e. memory retained by objects which are not support to keep the memory. 

Eclipse Memory Analyzer also allow you to browse through heap and execute SQL like queries into heap. 

This is one of my preferred tool to analyze tomcat OutOfMemory heap dump in production. I usually ask support team to copy them into development machine and from their I load them into MAT. It's also the most feature rich heap dump analyzer. 


That's all about how to take heap dump in Java and tomcat. I have shown you three ways to take heap dump from command line and a bonus way to take heap dump using Visual VM GUI tool. The heap dump is very useful while analyzing memory related issues in large Java applications e.g. Tomcat, WebSphere, WebLogic or JBoss. 

At the very least you should have the JVM option -XX:+HeapDumpOnOutOfMemoryError configured in Tomcat, JBoss or any Java application you care. Remember, the .hprof files are huge sometime more than 2GB and it also take sometime to generate, so don't do that during live production system, unless you know what you are doing.

Once you got the heap dump you can use jhat, jvisualvm, or eclipse memory analyzer (mat) to analyze the heap and find any potential memory leak in your Java application. 

References
Java Heap Analysis Tool (jhat)
jvisualvm
Java Memory Map (jmap)
jcmd
Eclipse Memory Analyzer (mat)

1 comment: