bcsb1001
bcsb1001

Reputation: 2907

StackOverflowError unexpected behaviour

I know that a StackOverflowError is thrown when recursion goes too deep (about 25000 recursions), but, after testing, I found that the exact amount of recursions before it is thrown (max stack size) changes between programs. Also, if I run an infinitely recursive method, say, 10 times, the SOE is thrown after a recursions the first time, and b recursions the next nine times (i.e. a different amount of recursions the first time). Also, both a and b differ between running my test multiple times.

Here is my class:

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        List<Integer> sizes = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            int size = doTest();
            System.out.println("Test " + i + " Yielded result " + size);
            sizes.add(size);
        }
        System.out.println("Average: " + average(sizes));
    }

    private static double average(Collection<Integer> ints) {
        int sum = 0;
        for (int i : ints) {
            sum += i;
        }
        return sum / (double) ints.size();
    }

    private static int executions = 0;

    private static int doTest() {
        try {
            recurse();
        } catch (StackOverflowError e) {
            int exec = executions;
            executions = 0;
            return exec;
        }
        throw new Error("Unexpected behaviour: StackOverflowError not thrown!"); // just to keep the compiler happy
    }

    @SuppressWarnings("InfiniteRecursion")
    private static void recurse() {
        executions++;
        recurse();
    }
}

My output looks like this:

Test 1 Yielded result 23004
Test 2 Yielded result 25060
Test 3 Yielded result 25060
Test 4 Yielded result 25060
Test 5 Yielded result 25060
Test 6 Yielded result 25060
Test 7 Yielded result 25060
Test 8 Yielded result 25060
Test 9 Yielded result 25060
Test 10 Yielded result 25060
Average: 24854.4

But, if I run my program again, it looks like this:

Test 1 Yielded result 23279
Test 2 Yielded result 25074
Test 3 Yielded result 25074
Test 4 Yielded result 25074
Test 5 Yielded result 25074
Test 6 Yielded result 25074
Test 7 Yielded result 25074
Test 8 Yielded result 25074
Test 9 Yielded result 25074
Test 10 Yielded result 25074
Average: 24894.5

Can someone tell me why these differences are occurring between programs, and on the first test?

Java version: 8 update 5

Upvotes: 1

Views: 86

Answers (1)

Peter Lawrey
Peter Lawrey

Reputation: 533820

The depth of recursion depends on your stack size and how fast you use it up. The exact stack size isn't always the same (exactly why I don't know) but you should avoid getting anywhere near this limit as another machine will be very different by default.

Upvotes: 4

Related Questions