Это может сработать, но обычно это плохая идея. Нет никаких гарантий, что ваше приложение успешно восстановится или что оно будет знать, если оно не удалось. Например:
На самом деле может быть не достаточно памяти для выполнения запрошенных задач, даже после выполнения шагов восстановления, таких как освобождение блока зарезервированной памяти. В этой ситуации ваше приложение может застрять в цикле, где оно, как представляется, несколько раз восстанавливается, а затем снова исчерпывает память.
OOME может быть брошен на любую нить. Если поток или библиотека приложения не рассчитаны на то, чтобы справиться с этим, это может привести к тому, что некоторая долговременная структура данных окажется в неполном или несовместимом состоянии.
Если потоки умирают в результате OOME, приложению может потребоваться перезапустить их как часть восстановления OOME. По крайней мере, это усложняет приложение.
Предположим, что поток синхронизируется с другими потоками, используя механизм уведомления / ожидания или какой-либо механизм более высокого уровня. Если этот поток умирает от OOME, другие потоки могут остаться в ожидании уведомлений (и т. Д.), Которые никогда не приходят ... например. Разработка этого может значительно усложнить приложение.
Таким образом, проектирование, реализация и тестирование приложения для восстановления из OOME может быть затруднено, особенно если приложение (или среда, в которой оно работает, или любая из используемых им библиотек) является многопоточным. Лучше рассматривать OOME как фатальную ошибку.
См. Также мой ответ на связанный вопрос:
РЕДАКТИРОВАТЬ - в ответ на следующий вопрос:
Другими словами, если OOME генерируется на сервере приложений (jboss / websphere / ..), нужно ли перезапустить его?
Нет, вам не нужно перезагружать . Но это, вероятно, разумно , особенно если у вас нет хорошего / автоматического способа проверки правильности работы службы.
JVM восстановится очень хорошо. Но сервер приложений и само приложение могут восстанавливаться, а могут и не восстанавливаться, в зависимости от того, насколько хорошо они предназначены для решения этой ситуации. (По моему опыту, некоторые серверы приложений не предназначены для этого, и что разработка и реализация сложного приложения для восстановления из OOMEs сложна, а правильное тестирование - еще сложнее.)
РЕДАКТИРОВАТЬ 2
В ответ на этот комментарий:
"другие темы могут остаться в ожидании уведомлений (и т. Д.), Которые никогда не приходят" Правда? Разве убитый поток не раскручивает свои стеки, высвобождая ресурсы по мере использования, включая удерживаемые блокировки?
Да, действительно! Учтите это:
Тема # 1 запускает это:
synchronized(lock) {
while (!someCondition) {
lock.wait();
}
}
// ...
Тема # 2 запускает это:
synchronized(lock) {
// do stuff
lock.notify();
}
Если поток № 1 ожидает уведомления, а поток № 2 получает OOME в разделе // do something
, то поток № 2 не сделает вызов notify()
, а поток № 1 может застрять в ожидании для уведомления, которое никогда не произойдет. Конечно, поток № 2 гарантированно освобождает мьютекс объекта lock
... но этого недостаточно!
Если код, выполняемый потоком, не является безопасным для исключения, то это более общая проблема.
«Безопасное исключение» - это не термин, о котором я слышал (хотя я знаю, что вы имеете в виду). Java-программы обычно не предназначены для обеспечения устойчивости к неожиданным исключениям. В самом деле, в сценарии, подобном описанному выше, скорее всего, трудно и невозможно сделать исключение приложения безопасным.
Вам понадобится какой-то механизм, посредством которого сбой потока # 1 (из-за OOME) превращается в уведомление о сбое связи между потоками в поток № 2.Эрланг делает это ... но не Java.Причина, по которой они могут сделать это в Erlang, заключается в том, что процессы Erlang взаимодействуют с использованием строгих CSP-подобных примитивов;т. е. нет разделения структур данных!
(Обратите внимание, что вышеупомянутую проблему можно получить практически для любого неожиданного исключения ... не только Error
исключений. Существуют определенные видыJava-кода, в котором попытка восстановления из неожиданного исключения может закончиться неудачно.)