4

When I run the code below, an OutOfMemoryError is thrown, but is not caught, despite the fact that there are clauses that should catch it:

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

The output is as follows:

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

The fact that the exception is not caught makes no sense to me. The OutOfMemoryError documentation confirms that the exception should be caught by either Throwable, Error, or OutOfMemoryError. (Note that the "java.lang." specifier does not affect the behavior.)

All the other questions that I've seen here on StackOverflow along the lines of "Why isn't my OutOfMemoryError exception being caught?" were posted by people who were only catching Exception objects, not Error or Throwable.

Any idea as to what's going on?

4

5 回答 5

16

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

于 2013-07-24T15:24:13.303 回答
12

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

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

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

我在Ideone.com 上制作了一个示例,您可以尝试一下。

于 2013-07-24T15:22:49.660 回答
0

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

如问题评论中所述:

测试 Zim-Zam O'Pootertoot 的想法并删除“+ err”并像 finally 一样执行一个字符串,看看你会得到什么结果。

于 2013-07-24T15:56:51.563 回答
0

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

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

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

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

于 2016-08-10T18:04:22.253 回答
-2

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

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

于 2013-07-24T15:26:19.857 回答