Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try-finally block prevents StackOverflowError

Take a look at the following two methods:

public static void foo() {     try {         foo();     } finally {         foo();     } }  public static void bar() {     bar(); } 

Running bar() clearly results in a StackOverflowError, but running foo() does not (the program just seems to run indefinitely). Why is that?

like image 767
arshajii Avatar asked Sep 15 '12 15:09

arshajii


People also ask

How do I stop StackOverflowError?

Increase Thread Stack Size (-Xss) Increasing the stack size can be useful, for example, when the program involves calling a large number of methods or using lots of local variables. This will set the thread's stack size to 4 mb which should prevent the JVM from throwing a java.

Can execution of finally block prevented?

You cannot skip the execution of the final block. Still if you want to do it forcefully when an exception occurred, the only way is to call the System. exit(0) method, at the end of the catch block which is just before the finally block.

Can you catch StackOverflowError java?

StackOverflowError is an error which Java doesn't allow to catch, for instance, stack running out of space, as it's one of the most common runtime errors one can encounter.

Does finally block always execute in java?

A finally block always executes, regardless of whether an exception is thrown. The following code example uses a try / catch block to catch an ArgumentOutOfRangeException.


1 Answers

It doesn't run forever. Each stack overflow causes the code to move to the finally block. The problem is that it will take a really, really long time. The order of time is O(2^N) where N is the maximum stack depth.

Imagine the maximum depth is 5

foo() calls     foo() calls        foo() calls            foo() calls               foo() which fails to call foo()            finally calls               foo() which fails to call foo()        finally            foo() calls               foo() which fails to call foo()            finally calls               foo() which fails to call foo()     finally calls        foo() calls            foo() calls               foo() which fails to call foo()            finally calls               foo() which fails to call foo()        finally            foo() calls               foo() which fails to call foo()            finally calls               foo() which fails to call foo() finally calls     foo() calls        foo() calls            foo() calls               foo() which fails to call foo()            finally calls               foo() which fails to call foo()        finally            foo() calls               foo() which fails to call foo()            finally calls               foo() which fails to call foo()     finally calls        foo() calls            foo() calls               foo() which fails to call foo()            finally calls               foo() which fails to call foo()        finally            foo() calls               foo() which fails to call foo()            finally calls               foo() which fails to call foo() 

To work each level into the finally block take twice as long an the stack depth could be 10,000 or more. If you can make 10,000,000 calls per second, this will take 10^3003 seconds or longer than the age of the universe.

like image 79
Peter Lawrey Avatar answered Oct 05 '22 22:10

Peter Lawrey