为什么导致 StackOverflowError 的递归方法的调用计数在程序运行之间会有所不同?
用于演示目的的简单类:
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在此特定示例中所做的工作的具体示例来证实这一理论,从而导致帧大小变化,那将是有益的。