为什么没有捕获“java.lang.OutOfMemoryError:Java堆空间”?

时间:2009-12-11 14:56:02

标签: java try-catch out-of-memory

我在Java Web应用程序中有一个线程导致 java.lang.OutOfMemoryError:Java堆空间异常,但是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中以调试模式显示在控制台中。

5 个答案:

答案 0 :(得分:40)

因为OutOfMemoryErrorError,而不是Exception。由于OutOfMemoryError不是Exception的子类,catch (Exception e)不适用。

OutOfMemoryError确实扩展了Throwable,所以你应该能够抓住它。这是一个SO discussion关于什么时候(如果有的话)你应该捕获错误。通常,由于您无法对此做任何事情,因此建议不要在生产代码中捕获错误。但是考虑到一个特殊情况,你试图调试正在发生的事情,它可能会有所帮助。

答案 1 :(得分:11)

java.lang.OutOfMemoryError不扩展java.lang.Exception,因此它不是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

答案 2 :(得分:3)

“〜错误”不是“〜例外”。

你必须抓住“错误”或“可投掷”

答案 3 :(得分:2)

OutOfMemoryError扩展了VirtualMachineError,而Exception直接扩展了Throwable。所以它不是按照Java规范捕获的。如果您希望捕获所有异常,请将catch(Throwable e)添加到该子句中,您将拥有它。

答案 4 :(得分:0)

我通常会在线程中添加一个'UncaughtExceptionHandler',所以如果你有任何泄漏,至少有机会记录这个问题并做一些清理工作。