I would like to detect an OutOfMemoryError
, take a heap dump, and automatically exit the Java program. Say I have the following command-line arguments for my JVM:
If you are using OpenJDK you can be sure when you are going to run the command set by -XX:OnOutOfMemoryError option.
Code taken from the OpenJDK source code. See: 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();
}
}
}
Just in case a short explanation:
So, for sure if you are using OpenJDK your process will dump memory and then quit.
In Java version 8u92 the VM arguments
-XX:+ExitOnOutOfMemoryError
-XX:+CrashOnOutOfMemoryError
were added, see the release notes.
ExitOnOutOfMemoryError
When you enable this option, the JVM exits on the first occurrence of an out-of-memory error. It can be used if you prefer restarting an instance of the JVM rather than handling out of memory errors.CrashOnOutOfMemoryError
If this option is enabled, when an out-of-memory error occurs, the JVM crashes and produces text and binary crash files.
Enhancement Request: JDK-8138745 (parameter naming is wrong though JDK-8154713, ExitOnOutOfMemoryError
instead of ExitOnOutOfMemory
)
I think this would heavily depend on the actual JVM implementation you are using. I'd like to believe that the JVM in use employs some intelligent ordering, first performing a heap dump than killing the machine. However, in my opinion you should not rely on the order of options.
You shall use
ExitOnOutOfMemoryError or CrashOnOutOfMemoryError
and
HeapDumpOnOutOfMemoryError
OpenJDK JVM (Hotspot) at first takes the heap dump and then crashes out or exits as opted for.
To get a clearer understanding you may refer to JVM source file taking care of this particular logic.
https://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/8641949eb21f/src/share/vm/utilities/debug.cpp
I would rather rely on calling into a script that handles the ordering more deterministically i.e.
-XX:OnOutOfMemoryError="/<SomeStandardLocation>/heapAndQuit.sh"
heapAndQuit.sh will then employ a method to find the pid
of the current process.
One simple way to identify the pid is to use the log file location your process is writing to
lsof | grep /var/tmp/<yourlogfileName> | cut -d " " -f1 | uniq
I will then use jmap
to dump and kill -9
subsequently