I'm surprised at how it is possible to continue execution even after a StackOverflowError
has occurred in Java.
I know that StackOverflowError
is a sublass of the class Error.
The class Error is decumented as "a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."
This sounds more like a recommendation than a rule, subtending that catching a Error like a StackOverflowError is in fact permitted and it's up to the programmer's reasonability not to do so. And see, I tested this code and it terminates normally.
public class Test
{
public static void main(String[] args)
{
try {
foo();
} catch (StackOverflowError e) {
bar();
}
System.out.println("normal termination");
}
private static void foo() {
System.out.println("foo");
foo();
}
private static void bar() {
System.out.println("bar");
}
}
How can this be? I think by the time the StackOverflowError is thrown, the stack should be so full that there is no room for calling another function. Is the error handling block running in a different stack, or what is going on here?
When the stack overflows and StackOverflowError
is thrown, the usual exception handling unwinds the stack. Unwinding the stack means:
... until the exception is caught. This is normal (in fact, necessary) and independent of which exception is thrown and why. Since you catch the exception outside of the first call to foo()
, the thousands of foo
stack frames that filled the stack have all been unwound and most of the stack is free to be used again.