代码之家  ›  专栏  ›  技术社区  ›  Crispy

为什么“JavaLang.OutOfMeMyLogError:Java堆空间”没有被捕获?

  •  9
  • Crispy  · 技术社区  · 14 年前

    我在Java Web应用程序中有一个线程导致了 JavaLang.OutOfMeMyLogError: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 回复  |  直到 9 年前
        1
  •  40
  •   Community Egal    7 年前

    因为 OutOfMemoryError 是一个 Error 不是一个 Exception . 自从 内存不足错误 不是的子类 例外 , the catch (Exception e) 不适用。

    内存不足错误 确实扩展 Throwable 但是,你应该能够抓住它。这是一个 SO discussion 你应该在什么时候(如果有)发现错误。一般来说,由于您不能对此做任何事情,建议您不要费心捕获生产代码中的错误。但在一个特殊的情况下,如果你试图调试正在发生的事情,它可能会有所帮助。

        2
  •  11
  •   Massimo Fazzolari    14 年前

    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());
    
         }
    }
    

    注意:异常和错误扩展了throwable,所以您也可以使用throwable来捕获两者。

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

        3
  •  3
  •   Jaco Van Niekerk    9 年前

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

    你必须抓住“错误”或“可丢弃”

        4
  •  2
  •   Daniil    14 年前

    OutOfMemoryError扩展了VirtualMachineError,而异常则直接扩展了Throwable。所以它不会像Java规范那样被捕获。如果您希望捕获所有异常,请在子句中添加catch(throwable e),这样您就拥有了它。

        5
  •  0
  •   Javamann    14 年前

    我通常要做的是在线程中添加一个“uncaughtexceptionhandler”,这样,如果您有任何泄漏,至少有机会记录该问题,并可能进行一些清理。