JVM не будет убит на OnOutOfMemoryError - PullRequest
0 голосов
/ 24 декабря 2018

Я использую JDK 1.8.0_u66, для которого опция -XX:+CrashOnOutOfMemoryError пока недоступна.Итак, я остановился на настройке -XX:OnOutOfMemoryError="kill -9 %p"

Хорошо, я написал следующее простое приложение:

public static void main(String[] args) throws Exception{
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    while (true) {
        new Thread(() -> {
            lock.lock();
            try {
                while (true) {
                    try{
                        condition.await();
                    } catch (Exception e){}
                }
            } finally {
                lock.unlock();
            }
        }).start();
    }
}

Приложение завершается с ошибкой

Exception in thread "main" java.lang.OutOfMemoryError: 
unable to create new native thread

в разделенииво-вторых, но это не убивает, как я ожидал, так как я установил опцию -XX:OnOutOfMemoryError="kill -9 %p".

Я предполагаю, что уничтожение JVM выполняется в отдельном Thread, но создать его невозможно, так как предел уже достигнут.Таким образом, приложение молча продолжает работать в несовместимом состоянии.

1 Ответ

0 голосов
/ 24 декабря 2018

Скорее всего, на вас воздействует JDK-8155004 , из-за которого -XX:OnOutOfMemoryError и связанные параметры не запускаются, когда OutOfMemoryError вызвано созданием потока.

Ваш текущий подход работает хорошо, когда OutOfMemoryError вызвано недостатком памяти кучи.Вы можете проверить это с помощью приведенного ниже кода и опции -XX:OnOutOfMemoryError="kill -9 %p".Выход из JVM 1.8.0_191 (ближе всего к вашей версии):

public static void main() {
  Thread t = new Thread(() -> {
    try {
      TimeUnit.HOURS.sleep(30);
    } catch (InterruptedException e) {}
  });
  t.start(); // to prevent natural JVM exit when main dies

  ArrayList<Long[]> retain = new ArrayList<>();
  while (true) {
    Long[] arr = new Long[Integer.MAX_VALUE];
    retain.add(arr);
  }
}
...