Java堆转储&关闭 - 什么命令?

时间:2013-10-17 17:50:44

标签: java jvm

我想检测OutOfMemoryError,进行堆转储,然后自动退出Java程序。假设我的JVM有以下命令行参数:

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

首先发生了什么?进程是否会转储内存然后退出,反之亦然?

5 个答案:

答案 0 :(得分:9)

如果您使用OpenJDK,您可以确定何时运行-XX:OnOutOfMemoryError选项设置的命令。

取自OpenJDK源代码的代码。请参阅: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();
    }
  }
} 

以防简短说明:

  1. 首先检查是否设置了HeapDumpOnOutOfMemoryError选项。在这种情况下,运行dump_heap_from_oome()
  2. 如果设置了OnOutOfMemoryError选项,则先运行report_java_out_of_memory()
  3. 所以,当然,如果您使用OpenJDK,您的进程将转储内存然后退出。

答案 1 :(得分:7)

我宁愿依赖于调用一个更有确定性地处理排序的脚本,即

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

heapAndQuit.sh将使用一种方法来查找当前进程的pid。 识别pid的一种简单方法是使用进程写入的日志文件位置

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

然后,我将使用jmap转储并随后kill -9

答案 2 :(得分:4)

在Java版本8u92中,VM参数

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

已添加,请参阅release notes

  

<强> ExitOnOutOfMemoryError
  启用此选项后,JVM将退出   第一次出现内存不足错误。如果你可以使用它   更喜欢重新启动JVM的实例而不是处理掉   记忆错误。

     

<强> CrashOnOutOfMemoryError
  如果启用此选项,则启用此选项   发生内存不足错误,JVM崩溃并生成文本和   二进制崩溃文件。

增强请求:JDK-8138745(参数命名错误JDK-8154713ExitOnOutOfMemoryError而不是ExitOnOutOfMemory

答案 3 :(得分:1)

我认为这在很大程度上取决于您使用的实际JVM实现。我想相信使用的JVM采用了一些智能排序,首先执行堆转储而不是杀死机器。但是,在我看来,你不应该依赖选项的顺序。

答案 4 :(得分:0)

您应使用

  

ExitOnOutOfMemoryError或   CrashOnOutOfMemoryError

  

HeapDumpOnOutOfMemoryError

OpenJDK JVM(热点)首先进行堆转储,然后崩溃或退出(如所选择的那样)。

为了更清楚地理解,您可以参考JVM源文件来处理这一特定逻辑。

https://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/8641949eb21f/src/share/vm/utilities/debug.cpp