Ashwin K Kumar
Ashwin K Kumar

Reputation: 113

StackOverflowError occurs multiple times

I was trying out this piece of code to understand exactly when a StackOverflowError occurs and how it behaves.

private static int testFunc(int i) {
    return i+1;
}

private static int add(int a){
    try {
        a = add(a);
    } catch(StackOverflowError e){
        System.out.println("StackOverflowError");
        return ++a;
    }
    return ++a;
}

public static void main(String[] args) throws Exception {
    char c = 'A';
    System.out.println((char)testFunc(c));
    int a = 0;
    System.out.println(add(a)); 
}

when I tried executing this code, I expected the recursion to stop when StackOverflowError occurs and the value printed to be one more than the depth of the available stack. But the StackOverflowError was caught multiple times. I got StackOverflowErrorStackOverflowErrorStackOverflowError.... printed about a 11 times. Although I used a System.out.println() statement, everything was printed on a single line. and the output printed was 0. it was printed only once.

Also, when I included a Thread.sleep(1000); statement inside the catch block, to identify why I was getting such a bizarre output, I got an even more weird output. The print statement inside the catch block was executed several times. Maybe more than 100, I dont have an exact count. Here, in the first few print statement execution(first 7-8 executions), everything was printed on the same line, after that everything was printed on a new line. But the overall wait time was at one second (due to the 1000ms sleep time) and the output was still 0.

Why do I get such an output and why does StackOverflowError works in this way?

UPDATE: I just realized I had a few more lines on my original code, which creates this behavior. Updated the code. Here is the actual output I got without the Thread.sleep(1000) statement.

B
stackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowError
0

UPDATE 2: I used the pre increment operator instead of the post increment operator and now I am getting a proper output for the stack depth. But if I remove the call to the testFunc(), the StackOverflowError statement is being printed only once before the stack depth is printed. But if I have those calls, it is being printed multiple times. Why is that so?

Upvotes: 2

Views: 257

Answers (1)

Max Vollmer
Max Vollmer

Reputation: 8598

Why multiple prints

System.out.println("StackOverflowError"); will call other methods internally, which will cause another StackOverflowError to be thrown. This happens after "StackOverflowError" was printed, but before the new line was printed.

Why sometimes only one print

The above explanation is a bit simplified. Actually it really depends on how much size is left on the stack after the first StackOverflowError was caught. Depending on the initial space left on your stack when starting the recursion, and on the amount of data each recursion adds to the stack, println() will behave differently:

  • If enough space is on the stack for a call to println():
    • You will get exactly one "StackOverflowError" in your console.
  • If there is not enough space on the stack for a call to println():
    • Either the call will throw before "StackOverflowError" was printed,
    • Or the call will throw after "StackOverflowError" was printed, but before the new line was printed,
    • Or the call will throw after "StackOverflowError" and the new line was printed.

This will then repeat until you're far enough down the recursion for println() to be called without an exception. So you can have 3 different outputs:

  • One "StackOverflowError" with a new line,
  • Multiple "StackOverflowError" with one new line,
  • Multiple "StackOverflowError" with multiple new lines.

In each case you might've gotten more exceptions than occurrences of "StackOverflowError" in your console.

Which result you get is totally undetermined.

Why 0

Because you use the post increment operator, therefore you always return 0.

Upvotes: 4

Related Questions