Java 堆栈中的可变消耗来自哪里?

Java 堆栈中的可变消耗来自哪里?,java,jvm,jit,jvm-hotspot,stack-overflow,Java,Jvm,Jit,Jvm Hotspot,Stack Overflow,当从JVM运行测试代码并调整JVM的线程堆栈大小时,我发现结果不一定是可重复的:有堆栈大小的值,程序有时会抛出java.lang.StackOverflowerError,但有时不会 我的问题是:是什么导致堆栈空间消耗的变化 此外,中断堆栈是否可以放在该程序的主线程上?对于其他JVM实现和/或操作系统,结果是否同样不确定 测试代码 后果 我没有观察到这种行为。在我的环境Windows 7 x64、1.6.0_19 x86 JDK中,它们在某一点上始终失败,然后在ss=1400时开始通过。由于它们

当从JVM运行测试代码并调整JVM的线程堆栈大小时,我发现结果不一定是可重复的:有堆栈大小的值,程序有时会抛出java.lang.StackOverflowerError,但有时不会

我的问题是:是什么导致堆栈空间消耗的变化

此外,中断堆栈是否可以放在该程序的主线程上?对于其他JVM实现和/或操作系统,结果是否同样不确定

测试代码 后果
我没有观察到这种行为。在我的环境Windows 7 x64、1.6.0_19 x86 JDK中,它们在某一点上始终失败,然后在ss=1400时开始通过。由于它们都通过了您的参数,因此我将其撞倒

我唯一改变的是没有指定类路径,我从与类文件相同的目录运行脚本。但即使在指定类路径时,我也得到了相同的结果

你确定你抓到的是StackOverflowerr吗?我会单独捕捉那个错误,而不是一般的一次性错误,以确保它不是其他错误,比如OutOfMemoryError

//...
} catch (StackOverflowError e) {
    System.exit(1);
}

这样,如果您得到的不是StackOverflower错误,它将打印stacktrace。

我没有观察到这种行为。在我的环境Windows 7 x64、1.6.0_19 x86 JDK中,它们在某一点上始终失败,然后在ss=1400时开始通过。由于它们都通过了您的参数,因此我将其撞倒

我唯一改变的是没有指定类路径,我从与类文件相同的目录运行脚本。但即使在指定类路径时,我也得到了相同的结果

你确定你抓到的是StackOverflowerr吗?我会单独捕捉那个错误,而不是一般的一次性错误,以确保它不是其他错误,比如OutOfMemoryError

//...
} catch (StackOverflowError e) {
    System.exit(1);
}

这样,如果它实际上不是StackOverflower错误,它将打印stacktrace。

如果它与热点编译器启动的时间有关,我不会感到惊讶,特别是在多核系统上运行时


编辑:要检查这一点,可以使用-Xint启动测试。如果您开始获得可复制的结果,那么不确定性行为可能是由热点编译器引起的。

如果它与热点编译器启动的时间有关,我不会感到惊讶,特别是如果您在多核系统上运行


编辑:要检查这一点,可以使用-Xint启动测试。如果您开始获得可复制的结果,那么不确定的行为可能是由热点编译器造成的。

BTW,堆栈大小为3700K时100%失败。BTW,堆栈大小为3700K时100%失败。这肯定是一个非常高的SOE跟踪,如下所示:$~/bin/stack-test.sh java.lang.stackOverflowerError at PointlessRecursion.addOnePointlessRecursion.java:7 at PointlessRecursion.addOnePointlessRecursion.java:7。。。我也会尝试另一个操作系统。谢谢你的数据点。我在Windows上的可变性变小了,但它仍然存在。对我来说,结果在1320k和1370k之间是不确定的。这肯定是一个非常高的SOE跟踪,如:$~/bin/stack-test.sh java.lang.StackOverflowerError at PointlesRecursion.AddOnePointlesRecursion.java:7 at PointlesRecursion.AddOnePointlesRecursion.java:7。。。我也会尝试另一个操作系统。谢谢你的数据点。我在Windows上的可变性变小了,但它仍然存在。对我来说,1320k到1370k之间的结果是不确定的!我花了一点时间用-Xint重新运行测试,可变性消失了。谢谢答对 了我花了一点时间用-Xint重新运行测试,可变性消失了。谢谢
$ java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
$ ~/bin/stack-test.sh
ss=2000 pass=0 fail=10
ss=2100 pass=1 fail=9
ss=2200 pass=0 fail=10
ss=2300 pass=2 fail=8
ss=2400 pass=1 fail=9
ss=2500 pass=1 fail=9
ss=2600 pass=2 fail=8
ss=2700 pass=6 fail=4
ss=2800 pass=3 fail=7
ss=2900 pass=1 fail=9
ss=3000 pass=3 fail=7
ss=3100 pass=3 fail=7
ss=3200 pass=6 fail=4
ss=3300 pass=2 fail=8
ss=3400 pass=4 fail=6
ss=3500 pass=10 fail=0
ss=3600 pass=9 fail=1
ss=3700 pass=10 fail=0
ss=3800 pass=10 fail=0
ss=3900 pass=10 fail=0
ss=4000 pass=10 fail=0
//...
} catch (StackOverflowError e) {
    System.exit(1);
}