Oct 25, 2019

How to get heap dump of Java Application?

There is a dedicated space where all the objects are stored at runtime. It is called heap. It is created at the time of JVM startup and is configurable using Xms (to be allocated at the time of JVM startup) and Xmx (maximum space to be sued heap) JVM options.

The JVM automatically performs Garbage Collection (GC) when it detects that the JVM is about to reach the max heap size. But the GC can only clean the objects which are eligible for GC. If the JVM can't allocate required memory even after GC, JVM will crash with "Exception in thread "main" java.lang.OutOfMemoryError: Java heap space".
If your Java application in production crashes due to some issue like this, you can't just ignore the incident and restart your application. You have to analyze the what caused the JVM to crash, and take the necessary actions to avoid it happening again. This is where the JVM heap dump comes into play.
If JVM heap dumps are by default disabled, you have to enable heap dumps explicitly by providing the following JVM option: -XX:+HeapDumpOnOutOfMemoryError.
The below sample code, tries to create a multiple, large arrays of chars, and keep the references in list. Which cause those large arrays ineligible for garbage collection.

package com.test;
import java.util.ArrayList;
import java.util.List;
public class TestClass {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<Object>();
        for (int i = 0; i < 1000; i++) {
            list.add(new char[1000000]);
        }
    }
}

If you run the above code with the following command lines:
1. java -XX:+HeapDumpOnOutOfMemoryError -Xms10m -Xmx3g com.test.TestClass
Result: Program runs and exits without any error. The heap size starts from 10MB and then grows as needed. Above program needs memory less than 3GB. So, it completes without any error.
2. java -XX:+HeapDumpOnOutOfMemoryError -Xms10m -Xmx1g com.test.TestClass
Result: JVM crashes with OOM.
If we change the above code a bit to remove the char array from the list, after adding to the list, this would be the result:

package com.test;
import java.util.ArrayList;
import java.util.List;
public class TestClass {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<Object>();
        for (int i = 0; i < 1000; i++) {
            list.add(new char[1000000]);
            list.remove(0);
        }
    }
}

3. java -XX:+HeapDumpOnOutOfMemoryError -Xms10m -Xmx10m com.test.TestClass
Result: This code runs without any issue even with a heap of 10MBs.

0 comments:

Post a Comment