I have a program in java, which runs infinite times.
Program code:
void asd()
{
try
{
//inside try block
System.out.println("Inside try !!!");
asd();
}
finally
{
//inside finally
System.out.println("Inside finally !!!");
asd();
}
}
OUTPUT : this program runs infinitely, by constantly printing both the sysouts.
My question : At some point, it starts throwing StackOverflowErrors from the try block and so it reaches the finally block, where we are again calling this function recursively. But how is the recursive function in the finally block being executed as we already facing a StackOverflowError?
How does the JVM handle this situation? Will the same behavior occur if we get OutOfMemoryErrors too?
If the exception is not handled at the higher level, the application crashes. The "finally" block execution stops at the point where the exception is thrown. Irrespective of whether there is an exception or not "finally" block is guaranteed to execute. Then the original exception that occurred in the try block is lost.
The Rule. The finally block on a try / catch / finally will always run — even if you bail early with an exception or a return .
A finally block always executes, regardless of whether an exception is thrown.
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs.
The problem is that your example program is pathological. It won't work, and it can't work.
But how the recursive function in the finally block gets executed as we already facing
StackOverflowError
.?
There is a rather complicated sequence of calls going on. Lets assume that the stack can hold 3 frames. A "hand execution" gives us a sequence of calls / call-stack snapshots as follows:
asd()
asd() > try
asd() > try > asd()
asd() > try > asd() > try
asd() > try > asd() > try > asd() // Stack Overflow!
asd() > try > asd() > finally
asd() > try > asd() > finally > asd() // Stack Overflow!
asd() > finally
asd() > finally > asd()
asd() > finally > asd() > try
asd() > finally > asd() > try > asd() // Stack Overflow!
asd() > finally > asd() > finally
asd() > finally > asd() > finally > asd() // Stack Overflow!
END
As you can see with a stack of depth 3, we made 7 calls, 4 of which failed with a stack overflow. If you do the hand execution for a stack of depth 4, you will get 15 calls, 5 => 31. The pattern is N => 2**N - 1 calls
.
In your case, the default stack is going to be able to accommodate hundreds, or even thousands of recursive calls.
Say N = 100. 2**100 is a very large number of calls. It is not infinite, but you will probably be dead before the program terminates.
How does the JVM handle this situation?
As above. The JVM is not doing anything special. The "effectively infinite loop" behaviour is entirely down to the way that your program is written.
Will the same behaviour occur if we get
OutOfMemoryError
s too?
Erm ... it depends on your program. But I'm sure you could concoct an example program that exhibited a similar pattern of behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With