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

Ala*_*lan 4 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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出如下:

'Finally' clause triggered
Exception in thread "main"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
Run Code Online (Sandbox Code Playgroud)

没有抓住异常这一事实对我来说毫无意义.该的OutOfMemoryError文档确认异常应该由任何Throwable的,错误或OutOfMemoryError异常捕获.(请注意,"java.lang."说明符不会影响行为.)

我在StackOverflow上看到的所有其他问题都是"为什么我的OutOfMemoryError异常没有被捕获?" 由只捕获异常对象的人发布,而不是错误或Throwable.

知道发生了什么事吗?

Zim*_*oot 16

你的异常处理程序内部正在尝试分配字符串"OutOfMemoryError=<" + oome + ">",但是你的内存不足,所以这可能会引发另一个OutOfMemoryError


Mar*_*nik 12

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

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

long[][] ary = new long[Integer.MAX_VALUE][Integer.MAX_VALUE];
Run Code Online (Sandbox Code Playgroud)

我在Ideone.com上做了一个样本,你可以尝试一下.