简体   繁体   中英

Java OutOfMemoryError not caught by clauses that catch Error and Throwable

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?

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

You should have provided the full stack trace of the OOME. It may easily have been thrown from the handler of the original OOME, masking it.

You have also failed to show the code which allocates a huge amount of memory. If you do this allocation in one huge block, then the allocation attempt will fail as a whole, leaving plenty of free memory behind. So, try with this code in your try block:

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

I have made a sample at Ideone.com, which you can try out.

I think it's because you are allocating more memory inside the catch and it's throwing yet another OutOfMemoryException.

As stated under the comment of the question:

Test Zim-Zam O'Pootertoot's idea and remove the " + err" and do a string just like in finally and see what results you get.

I cannot reproduce the problem described with Oracle Java 8.

To allocate huge memory I simply define array of size Integer.MAX_VALUE, and I get this exception:

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

Please try to recompile and please confirm you still have this problem with Oracle Java 8. Please publish exact statements which you commented out.

here you find some more info here Catching java.lang.OutOfMemoryError? and http://www.onjava.com/pub/a/onjava/2001/08/22/optimization.html

The problem in you code is how the JVM handles OOM exceptions. I think that the thread is killed (in this case the main one) thus your catch clause is unreachable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM