12

我在 Java Web 应用程序中有一个线程导致java.lang.OutOfMemoryError: Java heap space exception,但 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());

     }
}

输出:

最后。这一行确实执行
线程名称:_Worker-8
线程“_Worker-8”java.lang.OutOfMemoryError 中的异常:Java 堆空间
...

背景:

我最近接手了这个 Java 项目,我正在努力跟上 Java 和这个项目的速度。我是一名 C# 开发人员,所以我还不熟悉这个项目或 Java。我知道我可以使用 -Xmx 设置修复错误,但我有兴趣捕获此错误,以便记录它。该错误未显示在任何日志文件中,并且输出在 Eclipse 中以调试模式显示在控制台中。

4

5 回答 5

41

因为OutOfMemoryError是一个Error,不是一个Exception。因为OutOfMemoryError不是 的子类Exception,所以catch (Exception e)不适用。

OutOfMemoryError但是,确实 extend Throwable,所以你应该能够抓住它。这是关于何时(如果有的话)应该捕获错误的SO 讨论。通常,由于您对此无能为力,因此建议不要费心在生产代码中捕获错误。但是考虑到您尝试调试正在发生的事情的特殊情况,它可能会有所帮助。

于 2009-12-11T14:58:21.393 回答
12

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

于 2009-12-11T15:03:15.973 回答
3

“~Error”不是“~Exception”。

您必须捕获“错误”或“可投掷”

于 2009-12-11T14:58:22.877 回答
2

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

于 2009-12-11T15:00:22.810 回答
0

我通常会做的是向线程添加一个“UncaughtExceptionHandler”,这样如果你有任何泄漏,至少有机会记录问题并进行一些清理。

于 2009-12-11T22:27:50.890 回答