Если OutOfMemoryError
вызвано выделением прямого байтового буфера, тогда флаг JVM -XX:+ExitOnOutOfMemoryError
игнорируется.
Проверено на Oracle JDK и OpenJDK
Java-версия "1.8.0_144"
Java (TM) SE Runtime Environment (сборка 1.8.0_144-b01)
Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 25.144-b01, смешанный режим)
ОС: Ubuntu 16.04
для воспроизведения запустите следующий код
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
Программа выводит "OOME не завершает JVM!" и заканчивается кодом выхода 0.
Я ожидал, что он завершится с ошибкой и вернет код завершения больше 0. Он работает таким образом, когда OutOfMemory
выбрасывается из-за малого пространства кучи.
Если вы запустите следующий код с jvm args -Xmx10485760 -XX:+ExitOnOutOfMemoryError
, процесс jvm завершится с кодом выхода 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!");
}
Вывод кода выше будет:
Terminating due to java.lang.OutOfMemoryError: Java heap space
И это ожидаемое поведение, но оно не воспроизводится в первом примере.
Как сделать так, чтобы ExitOnOutOfMemoryError
работал в этом случае?
Может быть, есть обновленная JDK или альтернативная реализация JDK, у которой нет такой ошибки?
У меня есть проблема с druid.io. Если задание индекса в реальном времени встречает
java.lang.OutOfMemoryError: Direct buffer memory
зависает и не завершается.