当我运行下面的代码时,会抛出一个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。
知道发生了什么事吗?
答案 0 :(得分:16)
在您的异常处理程序内部,您尝试分配字符串"OutOfMemoryError=<" + oome + ">"
,但是内存不足,因此可能会抛出另一个OutOfMemoryError
答案 1 :(得分:12)
您应该已经提供了OOME的完整堆栈跟踪。它可能很容易从原始OOME的处理程序抛出,掩盖它。
您也无法显示分配大量内存的代码。如果你在一个巨大的块中进行这种分配,那么分配尝试将作为一个整体失败,留下大量的可用内存。因此,请在try
块中尝试使用此代码:
long[][] ary = new long[Integer.MAX_VALUE][Integer.MAX_VALUE];
做了样本
答案 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子句无法访问。