Функция jhat -baseline не работает с HeapDumpOnOutOfMemoryError и jcmd GC. сгенерированная базовая линия heap_dump
У меня внезапная утечка памяти, которая происходит довольно быстро, поэтому я должен поймать дамп с помощью HeapDumpOnOutOfMemoryError. Но чтобы увидеть, что на самом деле вызвало этот резкий всплеск памяти, мне нужно сначала взять базовый уровень, и я используюjcmd $pid GC.heap_dump baseline.hprof
для этого. Когда создается дамп кучи сбоя, и я говорю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-летней давности, описанных здесь. Почему не работает опция jhat -baseline? он сказал, что информация о дампе кучи, созданном с помощью 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.