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?

Alan
  • 1,889
  • 2
  • 18
  • 30
  • It also looks startling to me. Could something else be the reason, e.g. the OOME gettign thrown somewhere else than from where you expect it, hence it doesn't get caught? Examining the stacktrace might help. – Daniel S. Jul 24 '13 at 15:25
  • Helpful: http://stackoverflow.com/questions/5813614/what-is-difference-between-errors-and-exceptions `Throwable` errors are difficult to recover from. – austin Jul 24 '13 at 15:25
  • 1
    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. – user1132959 Jul 24 '13 at 15:26
  • Is that the only output you get? Is there any other stacktrace information? – jbx Jul 24 '13 at 15:26
  • 1
    possible duplicate of [Catching java.lang.OutOfMemoryError?](http://stackoverflow.com/questions/2679330/catching-java-lang-outofmemoryerror) – Damian Leszczyński - Vash Jul 24 '13 at 15:26
  • 1
    Good suggestion, @user1132959! When I don't try to write out the exception, I see that the OutOfMemoryError clause catches it. – Alan Jul 24 '13 at 15:32
  • Yes, that's the only output I get. There is no stack trace information. – Alan Jul 24 '13 at 15:33

5 Answers5

16

Inside of your exception handler you're trying to allocate the string "OutOfMemoryError=<" + oome + ">", but you're out of memory and so this is probably going to throw another OutOfMemoryError

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
12

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.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
0

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.

user1132959
  • 978
  • 8
  • 16
0

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.

Fuad Efendi
  • 155
  • 1
  • 9
-2

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.

Community
  • 1
  • 1
Elvis D.
  • 73
  • 1
  • 10