Tuesday, February 09, 2021

EpsilonGC and analyzing heap dump generated

Lets try to analyze the heap dump when our test program exits with OutOfMemoryError when run with EpsilonGC configuration. 

Code we use for this is the same test program we used in the previous post, which is 

class TestEpsilonGC {

    static final int ALLOCATION_SIZE = 1024 * 1024; // 1MB
    static final int LOOP_COUNT = 12;  
    static long start;

    public static void main(String[] args) {
        start();        
        for (int i = 0; i < LOOP_COUNT; i++) {
            System.out.print("Allocating iteration: "+i);
            byte[] array = new byte[ALLOCATION_SIZE];
            System.out.println(" Done");
        }
        end();
    }
    
    static void start() {
        start = System.currentTimeMillis();
}
    
    static void end() {
            System.out.println("Time taken: "+(System.currentTimeMillis() - start)+"ms");
    }
}

Now, lets run the below command to create the heap dump when the program exits with OutOfMemoryError

java -verbose:gc -Xmx10M -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+HeapDumpOnOutOfMemoryError TestEpsilonGC 

This creates the .hprof file in the folder under which you executed the above command. Analyzing it with IBM Heap Analyzer, we find that all objects allocated by the code are listed in the heap dump


In our case, all the byte array objects created before OutOfMemoryError got thrown is listed. 

Remember when analyzing heap dump generated with EpsilonGC configuration, objects occupying the heap space are not necessarily leaked objects. All objects ever created during the run gets listed in the heap dump.

You could use EpsilonGC to 
  • Verify the performance characteristics of your application without any interference of GC overhead
  • Benchmark the heap space to duration of run for your application before it runs out of memory
  • Study all objects getting created and validate it against the design intent of your application
  • You could even choose to use it as final configuration for your application if your application is short lived. In this case having intermittent GC cycles could be undesirable as when application terminates, it will release all the memory
  • Or this could be useful for certain batch processes which are non memory intensive, which can restart and continue where it left off from the previous run 

We could use a simple technique to restart self when OutOfMemoryError is thrown. The next post details how this can be done. 

Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/02/Garbage-Collection/EpsilonGC/analyzing-heap-dump

No comments:

Post a Comment