Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

  • foo(8073) calls foo(8074)
  • foo(8074) calls foo(8075) which dies
  • foo(8074) logs itself and calls bar(8075) which dies
  • foo(8074) dies and foo(8073) catches it, logs itself and calls bar(8074)
  • bar(8074) calls bar(8075) which dies, so bar(8074) logs itself
  • returning from all methods, gracefully shuts down

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.

like image 363
Carmine Avatar asked Jul 12 '26 12:07

Carmine


1 Answers

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.

like image 151
Karol Dowbecki Avatar answered Jul 15 '26 01:07

Karol Dowbecki



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!