SuperB
SuperB

Reputation: 33

How does a JVM die due to an OOM exception?

I've looked into a lot of places and couldn't find the reason for a JVM to die due to an OOM. I'm not considering the OS killer. To give some context, I have a Java application running and it starts to run out of memory, I know it may survive after the JVM start killing the threads.

However, I've seen it running for more than 30 minutes after the first OOM and it keeps running in this unresponsive state, it may or not recover. But, I've also seen it crashing right after the first OOM after replicating the same steps to trigger the OOM. The system is fine in the memory side, the problem is just with the JVM. So, my questions are:

  1. What happens to the JVM during an OOM that it may crash or remain permanently in an unresponsive state?
  2. How the JVM kill the threads? Is it random?

Upvotes: 3

Views: 1974

Answers (1)

Joachim Sauer
Joachim Sauer

Reputation: 308021

Technically an OutOfMemoryError is "just another throwable", so it may or may not kill the thread it is being thrown in, depending on how that Thread handles its exceptions.

For example, if it has a catch (Error e) block at the lowest level then it can "withstand" a lot of problems while still running.

So if your OutOfMemoryError is only thrown in threads that handle errors like this gracefully then your system can continue working just fine.

But that is also where the 2 unusual property of OutOfMemoryError comes into play:

  1. It can be thrown basically anywhere where memory is allocated and where exactly it will be thrown is so unpredictable as to look random. It's often thrown in the place that allocates the most memory, but that's by no means always true.
  2. Due to the nature of the error condition it represents it's quite possible to run into the exact same error again while trying to handle the exception (for example you might run out of memory while trying to generate a log message about running out of memory). This recursive nature makes reliably handling an OOME incredibly hard.

If you want to be truly resilient to OOMs in your application, you must ensure that all threads either gracefully handle OutOfMemoryErrors or are restarted correctly when they don't (via a watchdog or something similar). That's often quite difficult to do, especially when using any libraries that create their own threads.

So the tl;dr answers to your questions are:

  1. "it depends" on what your threads do to handle exceptions
  2. Threads will be killed by failing to handle either the initial exception or failing to handle the exception that happens while trying to handle the initial one. Which thread is getting hit is so unpredictable as to look random.

Upvotes: 4

Related Questions