Why is it possible to recover from a StackOverflowError?
When the StackOverflowError is thrown, the stack is full. However, when it's caught, all those foo
calls have been popped from the stack. bar
can run normally because the stack is no longer overflowing with foo
s. (Note that I don't think the JLS guarantees you can recover from a stack overflow like this.)
Because the stack doesn't actually overflow. A better name might be AttemptToOverflowStack. Basically what it means is that the last attempt to adjust the stack frame errs because there isn't enough free space left on the stack. The stack could actually have lots of space left, just not enough space. So, whatever operation would have depended upon the call succeeding (typically a method invocation), never gets exectued and all that is left is for the program to deal with that fact. Which means that it is really no different from any other exception. In fact, you could catch the exception in the function that is making the call.
When the stack overflows and StackOverflowError
is thrown, the usual exception handling unwinds the stack. Unwinding the stack means:
- abort the execution of the currently active function
- delete its stack frame, proceed with the calling function
- abort the execution of the caller
- delete its stack frame, proceed with the calling function
- and so on...
... 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.
When the StackOverFlow occurs, the JVM will pop down to the catch, freeing the stack.
In you example, it get rids of all the stacked foo.