How can we analyze JAVA memory issues (java.lang.OutOfMemoryError:Java heap space) using ECLIPSE MAT and Jprofiler: I

Prabhash Dilhan Akmeemana
6 min readSep 16, 2023

Let’s talk about Java out of memory issues type and how we can analyze those issues. If you configure the below JVM parameters, the JVM will create a heap-dump file with the heap-dump.hprof name when there is a java out-of-memory error

    -XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath="$CARBON_HOME/repository/logs/heap-dump.hprof" \

Heap dumps is a snapshot of the Java heap space. Let’s say you are observing a high memory issue intermittently and the application does not throw Java out of memory error, Then you can generate a heap dump manually(when the memory usage is high) using the below command and analyze it.

jmap -dump:file=heap_dump.hprof <pid>

There are lots of tools available to analyze heap dumps, but in this article series, I’m going to explain how we can utilize Eclipse memory analyzer (MAT)[1] and jprofiler[2] to analyze the heap dumps and find the root course of the out of memory issues.

First, let’s focus on identifying Java out of memory(OOM) error types and how we can analyze those issues.

java.lang.OutOfMemoryError: Java heap space

The detail message Java heap space indicates that objects could not be allocated in the Java heap. This error does not necessarily imply a memory leak. The problem can be as simple as a configuration issue, where the specified heap size (or the default size, if it is not specified) is insufficient for the application. You can define max and min heap allocation using the below JVM parameter.

-Xms: This parameter sets the initial size of the heap. For example, -Xms512m sets the initial heap size to 512 megabytes.

-Xmx: This parameter sets the maximum size of the heap. For example, -Xmx2g sets the maximum heap size to 2 gigabytes. The JVM will not allocate more memory for the heap than this value.

In other cases, the application unintentionally holds references to objects, and this prevents the objects from being garbage collected. That means there is a memory leak and you should fix it by analyzing the heap dump. Let’s say you observe an OOM heap space error in your Java application and a heap dump file is generated. Let’s see how we can use the MAT memory analyzer to check the heap dump.

First, you need to open the heap dump file.

If it is a large heap dump file, it will take some time to process. If it is a huge heap dump, there is a chance that an OOM issue might occur in the MAT memory analyzer. Ohhh !!! what to do now, we are going to analyze an OOM issue but the tool itself went to the OOM situation. Don’t worry, you can just increase the heap memory allocation in MAT and resolve your issue. You can increase the Xmx value in <MAT_HOME>/Eclipse/MemoryAnalyzer.ini and restart the MAT.

When opening the heap dump file, MAT will ask you whether you need to generate the leak suspect report, let’s enable that as well. It will give us a good overview of memory usage with a graph and show us what are the leak suspect objects that consume most of the memory.

Leak suspect reports show the suspected objects that consume most of the memory.

If you are well aware of your application code, and if the leak suspects indicate an object that is from your code base, you might have found the issue.

But as you can see in the above screenshot, it shows the leak suspect as java.lang.StringBuilder, which is a core Java-level object. In this kind of situation, you need to check what objects hold references to the StringBuilder from your code. In order to check that, you need to go to the dominator tree in the overview section.

Memory Analyzer provides a dominator tree of the object graph. The transformation of the object reference graph into a dominator tree allows you to easily identify the biggest chunks of retained memory and the keep-alive dependencies among objects. For more information, you can refer to the documentation[3].

From the dominator tree, again you will be able to see the objects which are consume the most memory. Let’s say you want to check references for the StringBuilder object, you can get the incoming references to the particular object by right-clicking on the objects and selecting the list objects option.

What is the incoming reference and outgoing reference mean, Let’s discuss this using the below example.

public class A {

private C c1 = C.getInstance();

}

public class B {

private C c2 = C.getInstance();

}

public class C {

private static C myC = new C();

public static C getInstance() {

return myC;

}

private D d1 = new D();

private E e1 = new E();

}

public class D {

}

public class E {

}

All the objects that hold reference object C are called ‘incoming references’. In this example, Object C’s incoming references are object A, object B, and class C.

All the objects that Object C references are called ‘outgoing references’. In this example, Object C’s outgoing references are object D, object E and class C.

I referred this example from the article in[4] where you can get a clear idea about the Java incoming and outgoing references.

Ok, now we know what incoming/outgoing references mean, As we discussed above, from the heap, we have found out that the StringBuilder object is consuming more heap. But that is a core java level object and we need to find the objects from our code base which uses the problematics stingbuilder objects. That means we need to find incoming references as mentioned above.

Now you may have found the root objects that hold references to the problematic StringBuilder object. From that information, you need to check your code and determine whether there is an issue with the particular class or whether it should clean the references to the StringBuilder object after using it or not. Let’s say it should keep the reference all the time. then you need to focus on the value inside the string builder and check whether it is an expected one or not. In order to check that, you can get the outgoing reference of the string builder object.

Likewise, you can get the incoming and outgoing references to a particular problematic object using MAT and determine the problem.

That’s it for this article, I will publish another article soon that explains how we can use jprofiler to analyze the heap dumps.

[1] https://eclipse.dev/mat/

[2] https://www.ej-technologies.com/products/jprofiler/overview.html

[3] https://help.eclipse.org/latest/index.jsp?topic=%2Forg.eclipse.mat.ui.help%2Fconcepts%2Fdominatortree.html

[4] https://blog.gceasy.io/2019/02/05/eclipse-mat-incoming-references-outgoing-references/#:~:text=Incoming%20References%20of%20object%20C,and%20uploaded%20to%20Eclipse%20MAT.

--

--