Простой класс для демонстрационных целей:
public class Main {
private static int counter = 0;
public static void main(String[] args) {
try {
f();
} catch (StackOverflowError e) {
System.out.println(counter);
}
}
private static void f() {
counter++;
f();
}
}
Я выполнил вышеуказанную программу 5 раз, результаты:
22025
22117
15234
21993
21430
Почему каждый раз разные результаты?
Я попытался установить максимальный размер стека (например -Xss256k
). Затем результаты были немного более последовательными, но снова не равными каждый раз.
Версия Java:
java version "1.8.0_72"
Java(TM) SE Runtime Environment (build 1.8.0_72-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.72-b15, mixed mode)
ИЗМЕНИТЬ
Когда JIT отключен (-Djava.compiler=NONE
), я всегда получаю тот же номер (11907
).
Это имеет смысл, поскольку оптимизация JIT, вероятно, влияет на размер кадров стека, и работа, выполняемая JIT, определенно должна варьироваться между исполнениями.
Тем не менее, я думаю, было бы полезно, если бы эта теория была подтверждена ссылками на некоторую документацию о теме и/или конкретными примерами работы, выполненной JIT в этом конкретном примере, что приводит к изменениям размера кадра.