2

addShutdownHook says:

In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly. This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows. The virtual machine may also abort if a native method goes awry by, for example, corrupting internal data structures or attempting to access nonexistent memory. If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.

When the Java heap runs out of memory and throws an OutOfMemoryError, does that cause the JVM to abort? Do heap OOMs cause native methods to go awry or corrupt internal data structures? Or are heap OOM errors recoverable enough for the shutdown hooks to be executed?

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
cozos
  • 787
  • 10
  • 19
  • 1
    Unlike events inside the JVM where the JVM ends and tries to go through it's orderly shutdown procedure, the OS killing your process simply stops the CPU at the instruction it was executing and removes the process from memory. There's nothing a process can do about it, it just disappears. The OS can also send a "terminate" signal to the process and the process would need to start shutdown, in that case the JVM could still run it's shutdown hooks – zapl Dec 09 '22 at 10:44
  • I think you're talking about a SIGKILL from something like the Linux OOM Killer - which the Java doc conclusively says will cause the JVM to abort (and therefore not guarantee shutdown hook execution). I'm curious about OOM errors internal to the Java process i.e. when the JVM cannot allocate any more memory on the heap - will it execute the shutdown hooks then? I suppose if the shutdown hooks need to also allocate objects on the heap it will also fail - but looking to hear more! – cozos Dec 09 '22 at 10:57
  • 1
    An OutOfMemoryError is just like other Errors and Exceptions something that happens on a regular basis, it's not going to automatically end your application, by not catching it, you chose the route of ending the application the regular way including shutdown hooks. OOM means that the memory managed by the JVM had no space for the one thing you wanted to put there. In case you have 700MB free heap, then try to put a 1GB array in there, you'll get an error and are still left with 700MB free heap afterwards which is plenty to continue with normal tasks. – zapl Dec 09 '22 at 11:16

1 Answers1

2

When the Java heap runs out of memory, the JVM will throw an OutOfMemoryError and may abort. Whether the JVM aborts or not depends on how the OutOfMemoryError is handled by the application. If the error is not caught and handled by the application, the JVM may choose to abort.

It is important to note that OutOfMemoryError is a runtime exception, so it is not required for the application to explicitly catch and handle it. However, if the application does catch and handle the error, it may be able to recover from the situation and continue running.

Whether or not the OutOfMemoryError causes native methods to go awry or corrupt internal data structures depends on how the error is handled by the application and by the JVM itself. In general, it is best to avoid letting the heap run out of memory, as this can cause unpredictable behavior.

If the JVM does not abort, it is possible for the shutdown hooks to be executed. Shutdown hooks are a mechanism for running specific cleanup code when the JVM is shutting down. However, if the JVM does abort, the shutdown hooks may not be executed.

Sunny
  • 14,522
  • 15
  • 84
  • 129
  • Thanks! So does that mean any kind of uncaught runtime exception causes the JVM to forcibly terminate via https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Runtime.html#halt(int)? And thus not call any shutdown hooks? – cozos Dec 09 '22 at 11:02
  • yes you are correct. – Sunny Dec 09 '22 at 11:19
  • Sorry I'm trying to understand this more. This seems to conflict with what @zapl in the comments saying above: "An OutOfMemoryError is just like other Errors and Exceptions something that happens on a regular basis, it's not going to automatically end your application, by not catching it, you chose the route of ending the application the regular way including shutdown hooks." - Am I misunderstanding? – cozos Dec 09 '22 at 11:46
  • It's depends on JVM implementation as I said earlier If the JVM does not abort, it is possible for the shutdown hooks to be executed. In most cases, when the JVM encounters an OutOfMemoryError, it will automatically shut down and the shutdown hooks may not be executed – Sunny Dec 09 '22 at 12:13
  • Do you know what this behavior is like for common JVM implementations? Say OpenJDK 11. Thanks for all your help BTW! – cozos Dec 12 '22 at 05:41
  • An `OutOfMemoryError` is not a `RuntimeException`, it is not an exception at all, it's an error. Your point that the application is not required to catch it stands, but with the caveat that the application may not even be able to handle the error (as you also describe). It probably sounds nitpicky, but the distinction between exception and error is there exactly for this reason. – daniu May 14 '23 at 13:39