Java堆转储和关闭-什么顺序?

时间:2022-08-22 13:42:09

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:

我希望检测OutOfMemoryError,获取堆转储,并自动退出Java程序。假设我的JVM有以下命令行参数:

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

Which happens first? Does the process dump memory and then quit, or the other way around?

最先发生?进程是转储内存然后退出,还是相反?

4 个解决方案

#1


6  

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

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

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

I will then use jmap to dump and kill -9 subsequently

然后我将使用jmap来转储并随后杀死-9

#2


8  

If you are using OpenJDK you can be sure when you are going to run the command set by -XX:OnOutOfMemoryError option.

如果您正在使用OpenJDK,您可以确定何时运行命令集by -XX:OnOutOfMemoryError选项。

Code taken from the OpenJDK source code. See: debug.cpp

从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();
    }
  }
} 

Just in case a short explanation:

以防万一。

  1. First of all check if the HeapDumpOnOutOfMemoryError option was set. In that case run dump_heap_from_oome()
  2. 首先检查是否设置了HeapDumpOnOutOfMemoryError选项。
  3. Sencondly if the OnOutOfMemoryError option was set, run report_java_out_of_memory()
  4. 如果设置OnOutOfMemoryError选项,则运行report_java_out_of_memory()

So, for sure if you are using OpenJDK your process will dump memory and then quit.

因此,如果您正在使用OpenJDK,那么您的进程将转储内存,然后退出。

#3


3  

In Java version 8u92 the VM arguments

在Java version 8u92中,VM参数。

  • -XX:+ExitOnOutOfMemoryError
  • - xx:+ ExitOnOutOfMemoryError
  • -XX:+CrashOnOutOfMemoryError
  • - 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.

启用此选项时,JVM会在第一次出现内存不足错误时退出。如果您希望重新启动JVM实例而不是处理内存错误,可以使用它。

CrashOnOutOfMemoryError
If this option is enabled, when an out-of-memory error occurs, the JVM crashes and produces text and binary crash files.

如果启用了这个选项,当出现内存不足错误时,JVM会崩溃并产生文本和二进制崩溃文件。

Enhancement Request: JDK-8138745 (parameter naming is wrong though JDK-8154713, ExitOnOutOfMemoryError instead of ExitOnOutOfMemory)

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

#4


1  

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.

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

#1


6  

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

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

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

I will then use jmap to dump and kill -9 subsequently

然后我将使用jmap来转储并随后杀死-9

#2


8  

If you are using OpenJDK you can be sure when you are going to run the command set by -XX:OnOutOfMemoryError option.

如果您正在使用OpenJDK,您可以确定何时运行命令集by -XX:OnOutOfMemoryError选项。

Code taken from the OpenJDK source code. See: debug.cpp

从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();
    }
  }
} 

Just in case a short explanation:

以防万一。

  1. First of all check if the HeapDumpOnOutOfMemoryError option was set. In that case run dump_heap_from_oome()
  2. 首先检查是否设置了HeapDumpOnOutOfMemoryError选项。
  3. Sencondly if the OnOutOfMemoryError option was set, run report_java_out_of_memory()
  4. 如果设置OnOutOfMemoryError选项,则运行report_java_out_of_memory()

So, for sure if you are using OpenJDK your process will dump memory and then quit.

因此,如果您正在使用OpenJDK,那么您的进程将转储内存,然后退出。

#3


3  

In Java version 8u92 the VM arguments

在Java version 8u92中,VM参数。

  • -XX:+ExitOnOutOfMemoryError
  • - xx:+ ExitOnOutOfMemoryError
  • -XX:+CrashOnOutOfMemoryError
  • - 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.

启用此选项时,JVM会在第一次出现内存不足错误时退出。如果您希望重新启动JVM实例而不是处理内存错误,可以使用它。

CrashOnOutOfMemoryError
If this option is enabled, when an out-of-memory error occurs, the JVM crashes and produces text and binary crash files.

如果启用了这个选项,当出现内存不足错误时,JVM会崩溃并产生文本和二进制崩溃文件。

Enhancement Request: JDK-8138745 (parameter naming is wrong though JDK-8154713, ExitOnOutOfMemoryError instead of ExitOnOutOfMemory)

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

#4


1  

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.

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