StackOverflowError意外行为

时间:2014-08-02 09:06:43

标签: java recursion stack-overflow

我知道当递归过深(大约25000次递归)时抛出StackOverflowError,但是,在测试之后,我发现精确递归之前的递归量(最大堆栈大小)程序之间的变化。另外,如果我运行一个无限递归方法,比如10次,那么在第一次 a 递归之后抛出SOE,并且 b 在接下来的9次递归(即a第一次不同的递归量)。此外, a b 在多次运行我的测试之间都有所不同。

这是我的班级:

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();
    }
}

我的输出如下:

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

但是,如果我再次运行我的程序,它看起来像这样:

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

有人可以告诉我为什么程序之间和第一次测试之间会出现这些差异吗?

Java版本:8更新5

1 个答案:

答案 0 :(得分:4)

递归的深度取决于您的堆栈大小以及您使用它的速度。确切的堆栈大小并不总是相同的(这正是我不知道的原因)但是你应该避免接近这个限制,因为默认情况下另一台机器会有很大的不同。