Java OutOfMemoryError未被捕获Error和Throwable的子句捕获

时间:2013-07-24 15:20:32

标签: java out-of-memory

当我运行下面的代码时,会抛出一个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异常没有被捕获?”由只捕获异常对象的人发布,而不是错误或Throwable。

知道发生了什么事吗?

5 个答案:

答案 0 :(得分:16)

在您的异常处理程序内部,您尝试分配字符串"OutOfMemoryError=<" + oome + ">",但是内存不足,因此可能会抛出另一个OutOfMemoryError

答案 1 :(得分:12)

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

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

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

我在Ideone.com, which you can try out.

做了样本

答案 2 :(得分:0)

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

如问题评论所述:

  

测试Zim-Zam O'Pootertoot的想法并删除“+ err”并做一个   字符串就像最后一样,看看你得到了什么结果。

答案 3 :(得分:0)

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

要分配大量内存,我只需定义大小为Integer.MAX_VALUE的数组,然后我得到以下异常:

var str = "abc,de 55,5gggggg,hhhhhh 666 "

请尝试重新编译,请确认您仍然遇到Oracle Java 8的这个问题。请发布您注释掉的确切语句。

答案 4 :(得分:-2)

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

代码中的问题是JVM如何处理OOM异常。

我认为线程被杀死(在本例中是主线程),因此你的catch子句无法访问。