Почему java.lang.OutOfMemoryError: пространство кучи Java не захвачено?

У меня есть поток в веб-приложении Java, который вызывает исключение java.lang.OutOfMemoryError: Java heap space, но блок try / catch не обнаруживает ошибку.

Пример кода:

private void doSomeWork()
{
     try
     {
         processData();  //Causes OutOfMemoryError
         System.out.println("This line does not execute");
     }
     catch (Exception e)
     {
         System.out.println("Exception.  This line does not execute.");
         //Log error
     }
     finally
     {
         System.out.println("finally.  This line does execute");
         System.out.println("Thread name: " + Thread.currentThread().getName());

     }
}

Вывод:

finally.  This line does execute 
Thread name: _Worker-8
Exception in thread "_Worker-8" java.lang.OutOfMemoryError: Java heap space
...

Справочная информация:

Недавно я взял на себя этот Java-проект и пытаюсь освоить Java и этот проект. Я разработчик C #, поэтому я еще не знаком ни с этим проектом, ни с Java. Я знаю, что могу исправить ошибку с помощью параметра -Xmx, но мне интересно отловить эту ошибку, чтобы я мог ее зарегистрировать. Ошибка не отображается ни в одном из файлов журналов, а вывод отображается на консоли в режиме отладки в Eclipse.


person Crispy    schedule 11.12.2009    source источник


Ответы (5)


Поскольку OutOfMemoryError является Error, не Exception. Поскольку OutOfMemoryError не является подклассом Exception, catch (Exception e) не применяется.

OutOfMemoryError действительно расширяет Throwable, однако , так что вы сможете его поймать. Вот обсуждение SO о том, когда (если вообще) следует обнаруживать ошибки. Как правило, поскольку вы ничего не можете с этим поделать, рекомендуется не беспокоиться об обнаружении ошибок в производственном коде. Но, учитывая особый случай, когда вы пытаетесь отладить, что происходит, это может быть полезно.

person Kaleb Brasee    schedule 11.12.2009
comment
Хороший ответ со ссылками. Я ценю это, спасибо! - person Crispy; 11.12.2009
comment
Я бы порекомендовал ловить бросаемые объекты в самой внешней части вашего приложения (или в самой внешней части метода потока), чтобы вы действительно могли знать, почему ваша программа была прервана (если никто другой не сделает это за вас) . - person Ravi Wallau; 12.12.2009

java.lang.OutOfMemoryError не расширяет java.lang.Exception, поэтому это не исключение. OutOfMemoryError расширяет java.lang.Error. Если вы хотите поймать ошибку, попробуйте следующее:

private void doSomeWork()
{
     try
     {
         processData();  //Causes OutOfMemoryError
         System.out.println("This line does not execute");
     }
     catch (Error e)
     {
         System.out.println("Exception.  This line does not execute.");
         //Log error
     }
     finally
     {
         System.out.println("finally.  This line does execute");
         System.out.println("Thread name: " + Thread.currentThread().getName());

     }
}

Примечание. Exception и Error расширяют Throwable, поэтому вы также можете использовать Throwable для перехвата обоих.

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Throwable.html

person Massimo Fazzolari    schedule 11.12.2009

«~ Ошибка» не является «~ исключением».

Вы должны поймать "Ошибка" или "Бросок"

person Dennis C    schedule 11.12.2009

OutOfMemoryError расширяет VirtualMachineError, а Exception напрямую расширяет Throwable. Так что это не ловится согласно спецификациям Java. ЕСЛИ вы хотите перехватить все исключения, добавьте в предложение catch (Throwable e), и он у вас будет.

person Daniil    schedule 11.12.2009
comment
чтобы быть более точным, OutOfMemoryError расширяет VirtualMachineError, который расширяет Error, и поскольку ошибки не являются исключениями, catch (Exception) не может его поймать - person chburd; 11.12.2009
comment
Бинго. Думал перечислить все дерево, но поленился :) - person Daniil; 11.12.2009

Обычно я добавляю UncaughtExceptionHandler в поток, чтобы, если что-то у вас возникнет, по крайней мере, у вас будет шанс зарегистрировать проблему и, возможно, выполнить некоторую очистку.

person Javamann    schedule 11.12.2009