Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java heap dump & shut down - what order?

Tags:

java

jvm

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:

-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?

like image 975
theeggman85 Avatar asked Oct 17 '13 17:10

theeggman85


People also ask

What is a Java heap dump?

A heap dump is a snapshot of all the objects in the Java Virtual Machine (JVM) heap at a certain point in time. The JVM software allocates memory for objects from the heap for all class instances and arrays.

Where is Java heap dump file?

By default the heap dump is created in a file called java_pidpid. hprof in the working directory of the VM, as in the example above. You can specify an alternative file name or directory with the -XX:HeapDumpPath= option.

Why heap dump is generated?

A heap dump is a snapshot of all the objects that are in memory in the JVM at a certain moment. They are very useful to troubleshoot memory-leak problems and optimize memory usage in Java applications. Heap dumps are usually stored in binary format hprof files.


2 Answers

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:

  1. First of all check if the HeapDumpOnOutOfMemoryError option was set. In that case run dump_heap_from_oome()
  2. Sencondly if the OnOutOfMemoryError option was set, run report_java_out_of_memory()

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

like image 109
Gooseman Avatar answered Sep 22 '22 17:09

Gooseman


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

like image 32
Ram Avatar answered Sep 19 '22 17:09

Ram