Я знаю, что StackOverflowError
бросается, когда рекурсия идет слишком глубоко (около 25000 рекурсий), но после тестирования я обнаружил, что точное количество рекурсий до того, как оно было выбрано (максимальный размер стека), изменяется между программами. Кроме того, если я запускаю бесконечно рекурсивный метод, скажем, 10 раз, то SOE бросается после рекурсий в первый раз, а b рекурсирует следующие девять раз (т.е. Другое количество рекурсий в первый раз). Кроме того, как 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
Глубина рекурсии зависит от размера вашего стека и от того, как быстро вы его используете. Точный размер стека не всегда одинаковый (именно поэтому я не знаю), но вы должны избегать приближения к этому пределу, поскольку по умолчанию другая машина будет совсем другой.
-XX:+PrintCompilation
Я подозреваю, что ваш код компилируется, поэтому после первого использования он использует немного меньше памяти.