Suppose the program is executing the asd()
method and the stack space is just about to end. Also suppose that instead of "inside try" and "inside finally" the method prints a counter that tells how far the stack you are:
void asd(int i){
try{
//inside try block
System.out.print(i);
System.out.println("t");
asd(i+1);
}
finally{
//inside finally
System.out.print(i);
System.out.println("f");
asd(i+1);
}
}
}
Now this is what the program does when it's just about to run out of stack space, when i
is 9154.
The call to println("t")
outputs the characters, and then goes on to call the println() method. This makes the program run out of stack space, so the execution is moved to the finally
block. The call to println there again runs out of stack space when printing the new line. The error is thrown again, and the execution moves on to the finally
in the activation frame above the current method call. This makes the program print f
for the second time, and since we've popped an activation frame from the stack this call now completes normally, and prints out a new line. The program has so far given this output:
...
9152t
9153t
9154t9154f9153f // notice we jumped to i=1953
Now, the method calls itself again, now from the finally block. The situation with the stack space is just like before, so the program executes like above, except that, since we were in a finally block for the method call of i=1953, the program execution ends up in the finally block of the method call of i=1952:
9154t9154f9152f
The finally block of i=9152 calls asd
again, passing i=9153, and since now there's enough stack space to print a complete line the method outputs from the try-block:
9153t
and then goes on to call itself, and in this call will end up running out of stack space again, giving the output:
9154t9154f9153f
... and the rest of the output can be explained in a similar manner:
9154t9154f9151f
9152t
9153t
9154t9154f9153f
9154t9154f9152f
9153t
9154t9154f9153f
9154t9154f9150f
9151t
9152t
9153t
...
What's important to notice is:
- The finally block is executed even in the case of a
StackOverflowError
.
- A program that has run into a
StackOverflowError
can be in an unpredictable state. Here the only observable effect is the fact that println
doesn't output a line break. In a more complex program this could mean that you can't trust the state of anything that the program had been working on, and that the safest thing to do is to bail out completely.