Функция jhat -baseline не работает с HeapDumpOnOutOfMemoryError и сгенерированной базовой линией jcmd G C .heap_dump - PullRequest
1 голос
/ 02 марта 2020

У меня внезапная утечка памяти, которая происходит довольно быстро, поэтому я должен перехватить дамп с помощью HeapDumpOnOutOfMemoryError. Но чтобы увидеть, что на самом деле вызвало этот огромный скачок памяти, мне нужно сначала взять базовый уровень, и для этого я использую jcmd $pid GC.heap_dump baseline.hprof. Когда создается дамп кучи cra sh, и я говорю jhat -baseline baseline.hprof java_pid1234.hprof, тогда я не получаю вычитание базовой линии должным образом, без разницы, добавляю ли я опцию -baseline или нет. Выходные данные говорят, что вычитание:

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.

, но это не имеет значения! Это почему? В 10-летних проблемах, о которых здесь сообщалось Почему не работает опция -baseline jhat? говорится, что информация о дампе кучи, сгенерированном с помощью jmap, несовместима, но я не использую jmap.

Есть ли способ, с помощью которого я могу вызвать точно такой же код, который использует этот HeapDumpOnOutOfMemoryError для создания базовой линии?

Думаю, я попытаюсь дважды вызвать этот дамп памяти. Но это очень неудобно, и [ОБНОВЛЕНИЕ] это даже не работает! Этот дамп памяти создается только один раз. Я создал эту функцию:

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];        
    }
}

, и когда я запускаю ее один раз, она делает это:

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

, но во второй раз, когда я вызываю ее, она делает это:

FOOM-0
... exception thrown

так, что это застревает!

PS: пожалуйста, не говорите мне об Eclipse или какой-то другой IDE, я работаю по существу без головы.

ОБНОВЛЕНИЕ: Я все еще хочу знать, почему это так, потому что это раздражает. Но я написал себе обходной путь:

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);     
}   

Это работает, потому что он использует ту же функцию dumpHeap, что и вещь OutOfMemory.

ДРУГОЕ ОБНОВЛЕНИЕ: Это, похоже, работает Цель это все еще не работает. Oracle Java 1,8 на Windows. Это было крайне неприятно. Я ничего не получил за всю эту работу. Я все еще вижу все базовые данные в гистограмме jhat.

...