vcmkrtchyan
vcmkrtchyan

Reputation: 2626

How java handles StackOverflowError?

Here's my sample app

public class Main {

    private long[] exceptionLevels = new long[1000];
    private int index;

    public static void main(String... args) {
        Main main = new Main();
        try {
            main.foo(0);
        } finally {
            Arrays.stream(main.exceptionLevels)
                    .filter(x -> x != 0)
                    .forEach(System.out::println);
        }
    }

    private void foo(int level) {
        try {
            foo(level + 1);
        } catch (StackOverflowError e) {
            exceptionLevels[index++] = level;
            bar(level + 1);
        }
    }

    private void bar(int level) {
        try {
            bar(level + 1);
        } catch (StackOverflowError e) {
            exceptionLevels[index++] = -level;
        }
    }
}

Sometimes, when I run the app, I see a result like this

8074
8073
-8074

Which actually means that the following occured

I get it, everything's fine. So there's an understandable pattern of getting

X, X-1, -X

for some max level for calls X

But sometimes, calling Main gives this kind of output

6962
6961
-6963

which is actually

X, X-1, -(X+1)

So the question is, how?

P.S. Also, when I change everything to static, the program totally changes it's behavior, so even sometimes I'm getting more than 3 results.

Edit: When I run this with -Xss228k I always get

1281
1280
-1281

but running with -Xss1m again brings me to random stack size and sometimes with the case described above.

Upvotes: 3

Views: 110

Answers (1)

Karol Dowbecki
Karol Dowbecki

Reputation: 44942

Running your code can result in few other possible outputs. On my PC (Java 8, Windows) I mostly get a pair of values like:

7053
-7055

but on rare occasions I get:

9667
9666
-9667

Catching any java.lang.Error is not recommended, it's an abnormal condition that JVM may not be able to recover from.

Upvotes: 2

Related Questions