【问题标题】:Java OutOfMemoryError not caught by clauses that catch Error and ThrowableJava OutOfMemoryError 未被捕获 Error 和 Throwable 的子句捕获
【发布时间】:2013-07-24 04:21:01
【问题描述】:

当我运行下面的代码时,会抛出 OutOfMemoryError,但没有被捕获,尽管有一些子句应该捕获它:

public class SomeClass {
    public static void main(String[] args) {
        try {
            //Allocate a huge amount of memory here
        } catch (OutOfMemoryError oome) {
            System.out.println("OutOfMemoryError=<" + oome + ">");
        } catch (Error err) {
            System.out.println("Error=<" + err + ">");
        } catch (Throwable t) {
            System.out.println("Throwable=<" + t + ">");
        } finally {
            System.out.println("'Finally' clause triggered");
        }
    }
}

输出如下:

'Finally' clause triggered
Exception in thread "main"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

异常未被捕获的事实对我来说毫无意义。 OutOfMemoryError documentation 确认异常应该被 Throwable、Error 或 OutOfMemoryError 捕获。 (请注意,“java.lang.”说明符不会影响行为。)

我在 StackOverflow 上看到的所有其他问题都是“为什么我的 OutOfMemoryError 异常没有被捕获?”是由只捕获 Exception 对象而不是 Error 或 Throwable 的人发布的。

知道发生了什么吗?

【问题讨论】:

  • 它看起来也让我吃惊。可能是其他原因,例如OOME gettign 被扔到您期望的其他地方,因此它不会被抓住?检查堆栈跟踪可能会有所帮助。
  • 有帮助:stackoverflow.com/questions/5813614/… Throwable 错误很难恢复。
  • 测试 Zim-Zam O'Pootertoot 的想法并删除“+ err”并像 finally 一样执行一个字符串,看看你得到了什么结果。
  • 好建议,@user1132959!当我不尝试写出异常时,我看到 OutOfMemoryError 子句捕获了它。

标签: java out-of-memory


【解决方案1】:

在您的异常处理程序中,您尝试分配字符串 "OutOfMemoryError=&lt;" + oome + "&gt;",但您的内存不足,因此这可能会引发另一个 OutOfMemoryError

【讨论】:

    【解决方案2】:

    您应该提供了 OOME 的完整堆栈跟踪。它可能很容易从原始 OOME 的 处理程序 中抛出,将其掩盖。

    您也未能展示分配大量内存的代码。如果您在一个巨大的块中执行此分配,那么分配尝试将作为一个整体失败,留下大量可用内存。因此,请尝试在您的 try 块中使用此代码:

    long[][] ary = new long[Integer.MAX_VALUE][Integer.MAX_VALUE];
    

    我在Ideone.com, which you can try out.做了一个样本

    【讨论】:

      【解决方案3】:

      我认为这是因为您在 catch 中分配了更多内存,而它又抛出了另一个 OutOfMemoryException。

      如问题评论所述:

      测试 Zim-Zam O'Pootertoot 的想法并删除“+ err”并执行 string 就像 in finally 一样,看看你得到了什么结果。

      【讨论】:

        【解决方案4】:

        我无法重现使用 Oracle Java 8 描述的问题。

        为了分配巨大的内存,我只定义了大小为 Integer.MAX_VALUE 的数组,我得到了这个异常:

        OutOfMemoryError=<java.lang.OutOfMemoryError: Requested array size exceeds VM limit>
        'Finally' clause triggered
        

        请尝试重新编译并确认您在使用 Oracle Java 8 时仍然存在此问题。请发布您已注释掉的确切语句。

        【讨论】:

          【解决方案5】:

          在这里您可以找到更多信息 Catching java.lang.OutOfMemoryError?http://www.onjava.com/pub/a/onjava/2001/08/22/optimization.html

          您代码中的问题是 JVM 如何处理 OOM 异常。我认为线程已被杀死(在这种情况下是主要线程),因此您的 catch 子句无法访问。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-11-04
            • 2019-06-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-11-05
            相关资源
            最近更新 更多