Andrew
Andrew

Reputation: 49606

Recursive call in the try-catch statement

I have the following snippet of code:

public static void main(String[] args) {
    foo();
}
public static void foo() {
    try {
        foo();
    } catch (Throwable t) {
        foo();
    }
}

Can anyone explain me what's going on here? In details, please.


I have changed this piece and added println methods to show something:

...
try {
    System.out.println("+");
    foo();
} catch (Throwable t) {
    System.out.println("-");
    foo();
}
...

I'm getting something like this (the process hasn't stopped):

+
+
+
+
+--
+--
+
+--
+--
+
+
+--
+--
+
+--
+--
+
+
+
+--
+--

Upvotes: 0

Views: 1403

Answers (2)

ZhongYu
ZhongYu

Reputation: 19682

The only way foo can exit is because of stackoverflow. We can simulate the effect by

public static void foo(int i)
{
    if(i>=N) return; // stack too deep

    foo(i+1);
    foo(i+1);
}

which is exponentially expensive w.r.t to the max stack depth.

On my machine, the time it takes is about 6ns * 2^N

The max stack depth is over 10,000, so it will take about

        10000000000000000000000000000000
        .... 
        (thousands of zeros)  
        ... 
        00000000000000000000000000000000 

years to finish the program, give or take a constant factor:)

Upvotes: 2

KhaledEz
KhaledEz

Reputation: 36

You are calling the same method indefinitely. This means the a StackOverflowError will be thrown.

But because you are catching it (StackOverflowError is not an exception, it is java.lang.Error, which is a java.lang.Throwable) the application will not stop, it will continue recursing, it will not stop at all.

When I tried to decrease the stack size to the minimum (-Xss160k -Xoss1k) it didn't help.

I know I didn't provide an explanation why this happens, I need to profile the code in order to get more information, but this is an interesting issue, maybe someone with deep expertise in JVM internals knows exactly what happened.

Upvotes: 2

Related Questions