1

I have a sudden memory leak which occurs fairly instantaneously so I must catch the dump with HeapDumpOnOutOfMemoryError. But to see what really caused this massive memory spike I need to take a baseline first, and I use jcmd $pid GC.heap_dump baseline.hprof for that. When the crash heap dump gets created, and I say jhat -baseline baseline.hprof java_pid1234.hprof then I do not get the baseline subtracted properly, it makes no difference whether or not I add the -baseline option. The output says it does the subtraction:

Snapshot resolved.
Reading baseline snapshot...
Dump file created Sun Mar 01 18:42:47 EST 2020
Resolving 10680567 objects...
Discovering new objects...
Started HTTP server on port 9999
Server is ready.

but it makes no difference! Why is that? In 10-year old issues reported here Why doesn't the -baseline option of jhat work? it said stuff about heap dump generated with jmap is incompatible but I'm not using jmap.

Is there some way I can invoke the exact same code as this HeapDumpOnOutOfMemoryError uses to create the baseline?

I think I will try to just trigger this memory dump twice. But it's very inconvenient, and [UPDATE] this doesn't even work! This memory dump is only created once. I created this function:

public static void forceOutOfMemory() {
    byte a[][] = new byte[100][];
    for(int i = 0; i < 100 ; i++) {
        System.err.println("FOOM-" + i);
        a[i] = new byte[1000000000];        
    }
}

and when I run this once it does this:

FOOM-0
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid12360.hprof ...
Heap dump file created [17509743 bytes in 0.085 secs]
... exception thrown

but the second time I call it it did this:

FOOM-0
... exception thrown

so that leaves me stuck!

PS: please don't tell me about Eclipse or some other IDE, I am running essentially headless.

UPDATE: I still want to know why that is so, because it's annoying. But I have written myself a workaround:

public static void dumpHeap(String name) throws Exception {
    java.util.List<com.sun.management.HotSpotDiagnosticMXBean> list = java.lang.management.ManagementFactory.getPlatformMXBeans(com.sun.management.HotSpotDiagnosticMXBean.class);
    java.io.File dump = new java.io.File(name + ".hprof");
    if(dump.exists())
        dump.delete();
    System.out.println("Dumping to file: " + dump.getAbsolutePath());
    list.get(0).dumpHeap(dump.getAbsolutePath(), true);     
}   

This works because it uses the same dumpHeap function that the OutOfMemory thing also uses.

ANOTHER UPDATE: This seemed to work, but for my purpose it still doesn't work. Oracle Java 1.8 on Windows. It was extremely frustrating. I got nothing for all of this work. I still see all the baseline data in the jhat histogram.

Gunther Schadow
  • 1,490
  • 13
  • 22

0 Answers0