Наконец блок будет выполняться в случае OutOfMemoryError?
Рассмотрим ниже код,
public class Test {
public void abc() {
try {
throw new OutOfMemoryError();
} finally {
System.out.println("finally");
}
}
public static void main(String[] args) {
new Test().abc();
}
}
Выход:
Exception in thread "main" finally
java.lang.OutOfMemoryError
at Test.abc(Test.java:5)
at Test.main(Test.java:12)
Так, finally
в этом случае выполняется блок, однако вышеприведенный вывод не фиксируется каждый раз.
Итак, вопрос в том, вот мы кидаем
OutOfMemoryError
а такжеfinally
блок исполняется. Это правда для каждого случая?Если да то
finally
блок будет выполнен, когдаOutOfMemoryError
будет брошено в реальность, значит расширение области памяти будет выполнено во время выполнения и недостаточно памяти?
2 ответа
Все будет интересно, если вы попытаетесь что-то сделать в блоке finally, требующем дополнительной памяти:
public class Finally {
public void abc() {
try {
throw new OutOfMemoryError();
} finally {
byte[] b = new byte[1024*1024*1024];
System.out.println("finally");
}
}
public static void main(String[] args) {
new Finally().abc();
}
}
Теперь, когда вы выполняете код (java -Xmx20m Finally
например), вы можете легко оказаться в ситуации, когда доступная куча была исчерпана до такой степени, что finally
блок не может быть полностью завершен, поэтому его выполнение не может быть гарантировано. Поэтому я не рекомендовал бы полагаться на блоки наконец в случае OutOfMemoryErrors
,
Это верно, как сказал Сотириос Делиманолис
и что еще более удивительно, даже если вы поместите возврат в свой блок try, будет наконец выполнен
Из документа:
"Блок finaly позволяет программисту избежать случайного обхода кода очистки при возврате, продолжении или разрыве. Помещение кода очистки в блок finally всегда является хорошей практикой, даже если исключений не ожидается"
проверьте это для получения дополнительной информации http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html