2013-10-17 21 views
10

Vorrei rilevare un OutOfMemoryError, fare un dump dell'heap e uscire automaticamente dal programma Java. Supponiamo di avere i seguenti argomenti da riga di comando per la mia JVM:Dump dell'heap Java e arresto - quale ordine?

-XX:OnOutOfMemoryError="kill -9 %p" 
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/tmp 

Che cosa succede prima? Il processo esegue il dump della memoria e quindi esce, o viceversa?

+0

Non pratico uccidere. Avere un try-catch di livello superiore e fare un syste.exit. –

risposta

6

avrei preferito affidarsi a mettere in uno script che gestisce l'ordinamento più deterministicamente cioè

-XX:OnOutOfMemoryError="/<SomeStandardLocation>/heapAndQuit.sh" 

heapAndQuit.sh sarà poi impiegare un metodo per trovare l'pid del processo corrente. Un modo semplice per identificare il PID è quello di utilizzare il percorso del file di registro il processo sta scrivendo

lsof | grep /var/tmp/<yourlogfileName> | cut -d " " -f1 | uniq 

Io poi usare jmap per scaricare e kill -9 successivamente

+0

Questo è quello che ho iniziato a fare invece, finora sembra essere l'opzione più estensibile. Grazie! – theeggman85

+0

Per tomcat, il modo più elegante per trovare pid è 'TOMCATPID = $ (cat tomcat.pid)' – kubanczyk

1

Penso che questo dipenderebbe molto dall'attuale implementazione JVM che si sta utilizzando. Mi piacerebbe credere che la JVM in uso impieghi alcuni ordini intelligenti, prima di eseguire un dump dell'heap che uccidere la macchina. Tuttavia, a mio parere non si dovrebbe fare affidamento sull'ordine delle opzioni.

7

Se si utilizza OpenJDK, si può essere sicuri quando si eseguirà il comando impostato da -XX: opzione OnOutOfMemoryError.

Codice preso dal codice sorgente OpenJDK. Vedere: debug.cpp

void report_java_out_of_memory(const char* message) { 
    static jint out_of_memory_reported = 0; 

    // A number of threads may attempt to report OutOfMemoryError at around the 
    // same time. To avoid dumping the heap or executing the data collection 
    // commands multiple times we just do it once when the first threads reports 
    // the error. 
    if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) { 
    // create heap dump before OnOutOfMemoryError commands are executed 
    if (HeapDumpOnOutOfMemoryError) {  
     tty->print_cr("java.lang.OutOfMemoryError: %s", message); 
     HeapDumper::dump_heap_from_oome(); 
    } 

    if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { 
     VMError err(message); 
     err.report_java_out_of_memory(); 
    } 
    } 
} 

Nel caso in cui una breve spiegazione:

  1. Prima di tutto verifica se l'opzione è stata impostata HeapDumpOnOutOfMemoryError. In tal caso dump_heap_from_oome run()
  2. Sencondly se l'opzione è stata impostata OnOutOfMemoryError, report_java_out_of_memory eseguire()

Quindi, di sicuro se si utilizza il processo di OpenJDK sarà il dump della memoria e quindi chiudere.

2

In Java versione 8u92 gli argomenti VM

  • -XX:+ExitOnOutOfMemoryError
  • -XX:+CrashOnOutOfMemoryError

sono stati aggiunti, vedere release notes.

ExitOnOutOfMemoryError
Quando si attiva questa opzione, la JVM esce al primo verificarsi di un errore out-of-memoria. Può essere utilizzato se si preferisce riavviare un'istanza della JVM anziché gestire gli errori di memoria .

CrashOnOutOfMemoryError
Se questa opzione è abilitata, quando si verifica un errore di out-of-memoria, crash JVM e produce il testo e file di crash binari.

Enhancement Richiesta: JDK-8138745 (parametro di denominazione è sbagliato però JDK-8154713, ExitOnOutOfMemoryError invece di ExitOnOutOfMemory)

Problemi correlati