Если уловка OutOfMemoryError
сильно обескуражена, поскольку вы, возможно, не знаете условия JVM после обнаружения ошибки, почему JVM просто не прерывает и не уведомляет пользователя, а не бросает ошибку?
Почему JVM просто не заканчивается, а бросает OOME?
Ответ 1
Потому что нет единого стандартного способа сообщить пользователю об ошибке. Выброс ошибки позволяет объекту быть пойманным на верхнем уровне, и отчет о состоянии, однако, может быть уместным (сообщение консоли, запись в файл журнала, отображение диалога и т.д.) До завершения. В документации указано, что разумные приложения не должны ломать Ошибки, что верно: лучший способ их обработки - это код рамки, так как существует очень мало (хотя и не ноль) изменений в том, как их можно обрабатывать. В частности, они не могут быть реально восстановлены, поэтому большинство авторов приложений пытаются их поймать.
Обновление: есть и другая причина. Выброс ошибки не только позволяет поймать ошибку: она также вызывает выполнение кода в блоках "finally". Поскольку эти блоки могут включать критический код очистки, важно, чтобы они были разрешены для запуска до завершения приложения.
Ответ 2
Потому что вы могли бы знать, что делать и как это сделать.
Пример: ваш код (попытки) создает массив с несколькими десятками миллионов элементов (в зависимости от ввода). По всей вероятности, это будет OutOfMemoryException
. В частности, можно создать только создание массива в блоке try/catch. После исключения память, скорее всего, будет в довольно приличном уровне (массив либо полностью выделен, либо вообще не выделен). Ваша программа может продолжить выполнение. Даже создайте сообщение об ошибке, отправьте электронное письмо или выполните любые другие корректирующие действия и приступите к следующему вводу (от пользователя, партии и т.д.).
Такие заметки об уклонении обычно нацелены на начинающего/среднего разработчика. Один, который попытается поймать исключение на верхнем уровне программы, например, где нет подробностей о том, что вызвало его.
Ответ 3
У вас есть возможность сбросить данные или определить причину OOME другими способами, когда приложение не завершено.
Если он не обнаружен, он завершает THREAD, из которого была инициирована ошибка. Другие потоки продолжают работать просто отлично, если, конечно, они также не вызывают OutOfMemoryErrors.
Если вы хотите убить свою JVM независимо от того, потому что вы подозреваете, что она может находиться в несогласованном состоянии, добавьте это в свои варианты java:
-XX:OnOutOfMemoryError="kill -9 %p"
Ответ 4
Throwables (Исключения, ошибки) являются стандартным способом для JVM уведомлять пользователей о проблемах. Это не для того, чтобы поймать его, но иметь журнал о том, что произошло, где и когда. Создание некоторого метода для выполнения логики после OOM не является верным, поскольку статус JVM может быть непоследовательным, и логика уведомления никогда не будет выполнена.
Кроме того, в качестве бесплатного действия вы также можете запросить, чтобы ошибки OOM генерировали дамп, который вы можете просмотреть позже (используя анализаторы дампов) и найти утечки памяти в своих приложениях, используя
-XX:+HeapDumpOnOutOfMemoryError
Ответ 5
Выбрасывая OutOfMemoryError, есть вероятность, что что-то где-то может иметь достаточно памяти для получения исключения и записи того факта, что это произошло (например, регистратор или stdout). Вероятно, программа должна выйти, а не пытаться продолжить работу в потенциально недействительном состоянии.
Несмотря на то, что эта попытка записи/регистрации OutOfMemoryError может завершиться неудачно, потому что у системы нехватка памяти, есть также хороший шанс, что она может преуспеть. Если JVM в итоге выходит из OOM, существует нулевая вероятность того, что проблема будет записана. Нетрадиционная вероятность записи проблемы лучше, чем нулевая вероятность записи проблемы.