'-XX:+ExitOnOutOfMemoryError ignored on 'java.lang.OutOfMemoryError: Direct buffer memory'
If the OutOfMemoryError
is caused by allocating a direct byte buffer than the JVM flag -XX:+ExitOnOutOfMemoryError
is ignored.
Checked on Oracle JDK and OpenJDK Java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
OS: Ubuntu 16.04
to reproduce run the following code
package com.company;
import java.nio.ByteBuffer;
public class Main {
public static void main(String[] args) {
// This should guarantee to throw:
try {
ByteBuffer bb = ByteBuffer.allocateDirect(10485760*2);
System.out.println("OOME not triggered");
} catch (OutOfMemoryError err) {
System.out.println("OOME didn't terminate JVM!");
}
}
}
jvm args: -XX:MaxDirectMemorySize=10485760 -XX:+ExitOnOutOfMemoryError
The program outputs "OOME didn't terminate JVM!" and terminates with exit code 0.
I expected it to crash and return exit code greater than 0. It works in this way when OutOfMemory
is thrown due to low heap space.
If you run the following code with jvm args -Xmx10485760 -XX:+ExitOnOutOfMemoryError
then the jvm process will crash with exit code 3:
try {
byte[] b = new byte[10485760*2];
System.out.println("OOME not triggered");
} catch (OutOfMemoryError err) {
System.out.println("OOME didn't terminate JVM!");
}
The output of the code above will be:
Terminating due to java.lang.OutOfMemoryError: Java heap space
And this is the expected behavior but that is not reproduced with the first example.
How to make ExitOnOutOfMemoryError
option to work for this case?
Maybe there is an updated JDK or alternative JDK implementation that doesn't have such bug?
I have this problem with druid.io. If real-time index task encounters
java.lang.OutOfMemoryError: Direct buffer memory
it hangs and doesn't terminate.
Solution 1:[1]
According to a discussion on the Java issue tracker, ExitOnOutOfMemoryError
is only intended to cover OutOfMemory errors thrown by the JVM itself. NIO buffers are allocated from native code and so OOM errors related to them are also thrown from native code, so unfortunately this appears to be the intended behaviour.
- The behaviour is discussed in this issue: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8257790
- Another issue requests that more detail to the
ExitOnOutOfMemoryError
description: https://bugs.openjdk.java.net/browse/JDK-8258058- This is the commit that adds extra detail — it limits the OOM Errors handled to those that are thrown from the JVM: https://github.com/openjdk/jdk/commit/0c8cc2cd
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Hal |