java递归深度限制_java – 为什么最大递归深度可以达到非确定性?

观察到的行为受到HotSpot优化器的影响,但不是唯一的原因。当我运行下面的代码

public static void main(String[] argv) {

System.out.println(System.getProperty("java.version"));

System.out.println(countDepth());

System.out.println(countDepth());

System.out.println(countDepth());

System.out.println(countDepth());

System.out.println(countDepth());

System.out.println(countDepth());

System.out.println(countDepth());

}

static int countDepth() {

try { return 1+countDepth(); }

catch(StackOverflowError err) { return 0; }

}

启用JIT,我得到的结果如下:

> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -cp build\classes X

1.8.0_40-ea

2097

4195

4195

4195

12587

12587

12587

> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -cp build\classes X

1.8.0_40-ea

2095

4193

4193

4193

12579

12579

12579

> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -cp build\classes X

1.8.0_40-ea

2087

4177

4177

12529

12529

12529

12529

在这里,JIT的效果是清晰可见的,显然优化的代码需要更少的堆栈空间,并且显示分层编译已启用(实际上,使用-XX:-TieredCompilation显示单个跳转,如果程序运行足够长)。

相比之下,使用禁用JIT,我得到以下结果:

> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -Xint -cp build\classes X

1.8.0_40-ea

2104

2104

2104

2104

2104

2104

2104

> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -Xint -cp build\classes X

1.8.0_40-ea

2076

2076

2076

2076

2076

2076

2076

> f:\Software\jdk1.8.0_40beta02\bin\java -Xss68k -server -Xint -cp build\classes X

1.8.0_40-ea

2105

2105

2105

2105

2105

2105

2105

这些值仍然有所不同,但不在单个运行时线程中,而且数量较小。

因此,如果优化器可以减少每个方法调用所需的堆栈空间,那么(相当小的)差异会变得更大。由于内联。

什么可以造成这样的差异?我不知道这个JVM是如何实现的,但是一个场景可能是堆栈限制被强制执行的方式需要堆栈结束地址的一定对齐(例如匹配内存页大小),而内存分配则返回内存与起始地址有较弱的一致保证。将这样的场景与ASLR组合,并且在对齐要求的大小内可能总是有差异。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值