Java 堆转储和关闭 - 什么顺序?
我想检测一个,采取堆转储,并自动退出Java程序。假设我的JVM有以下命令行参数:OutOfMemoryError
-XX:OnOutOfMemoryError="kill -9 %p"
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/tmp
哪个先发生?进程是转储内存然后退出,还是相反?
我想检测一个,采取堆转储,并自动退出Java程序。假设我的JVM有以下命令行参数:OutOfMemoryError
-XX:OnOutOfMemoryError="kill -9 %p"
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/tmp
哪个先发生?进程是转储内存然后退出,还是相反?
如果您使用的是OpenJDK,则可以确定何时要运行-XX:OnOutOfMemoryError选项设置的命令。
代码取自 OpenJDK 源代码。请参见:调试.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();
}
}
}
以防万一简短的解释:
因此,可以肯定的是,如果您使用的是OpenJDK,您的进程将转储内存,然后退出。
我宁愿依靠调用一个脚本来更确定地处理排序,即
-XX:OnOutOfMemoryError="/<SomeStandardLocation>/heapAndQuit.sh"
然后,heapAndQuit.sh 将采用一种方法来查找当前进程。识别 pid 的一种简单方法是使用进程写入的日志文件位置pid
lsof | grep /var/tmp/<yourlogfileName> | cut -d " " -f1 | uniq
然后我将使用转储和随后jmap
kill -9