java 栈 大小_如何增加Java堆栈大小?

我问这个问题去了解如何增加JVM中的运行时调用堆栈大小。我有一个答案,我还有很多有用的答案和评论与Java如何处理需要大型运行时栈的情况相关。我已经用答复的总结扩展了我的问题。

最初我想增加JVM堆栈大小,所以程序喜欢运行没有StackOverflowError。

public class TT {

public static long fact(int n) {

return n < 2 ? 1 : n * fact(n - 1);

}

public static void main(String[] args) {

System.out.println(fact(1 << 15));

}

}

相应的配置设置是具有足够大的值的java -Xss …命令行标志。对于上面的程序TT,它的工作原理像这样与OpenJDK的JVM:

$ javac TT.java

$ java -Xss4m TT

其中一个答案还指出,-X …标志是实现相关的。我在使用

java version "1.6.0_18"

OpenJDK Runtime Environment (IcedTea6 1.8.1) (6b18-1.8.1-0ubuntu1~8.04.3)

OpenJDK 64-Bit Server VM (build 16.0-b13, mixed mode)

也可以只为一个线程指定一个大堆栈(参见其中一个答案)。这是建议超过java -Xss …以避免浪费内存不需要它的线程。

我很好奇程序上面的程序栈有多大,所以我运行它n增加:

> -Xss4m可以足够用于事实(1 <<15)

> -Xss5m可以足够用于事实(1 << 17)

> -Xss7m对于事实可以是足够的(1 <<18)

> -Xss9m对于事实可以足够(1 <<19)

> -Xss18m可以足够用于事实(1 <<20)

> -Xss35m可以足够用于事实(1 << 21)

> -Xss68m可以足够用于事实(1 <<22)

> -Xss129m可以足够用于事实(1 << 23)

> -Xss258m可以足够用于事实(1 <<24)

> -Xss515m可以足够用于事实(1 <25)

从上面的数字,似乎Java使用大约16字节每堆栈帧的上述功能,这是合理的。

上面的枚举包含可以足够而不是足够,因为堆栈要求不是确定性的:使用相同的源文件运行它多次,并且相同的-Xss …有时成功,有时会产生StackOverflowError。例如。对于1 < 20,-Xss18m足够在10次中的7次运行,并且-Xss19m也不总是足够,但-Xss20m是足够的(100次中的所有100次运行)。垃圾收集,JIT插入,还是其他原因导致这种非确定性的行为? 在StackOverflowError(以及可能还有其他异常)处打印的堆栈跟踪仅显示运行时堆栈的最近的1024个元素。下面的答案演示了如何计算到达的精确深度(可能大于1024)。 许多响应的人已经指出,它是一个好的和安全的编码实践,考虑替代的,更少的堆栈饥饿的实现相同的算法。通常,可以将一组递归函数转换为迭代函数(使用例如Stack对象,该对象被填充在堆上而不是运行时栈上)。对于这个特定的事实函数,它是很容易转换它。我的迭代版本将如下所示:

public class TTIterative {

public static long fact(int n) {

if (n < 2) return 1;

if (n > 65) return 0; // Enough powers of 2 in the product to make it (long)0.

long f = 2;

for (int i = 3; i <= n; ++i) {

f *= i;

}

return f;

}

public static void main(String[] args) {

System.out.println(fact(1 << 15));

}

}

FYI,如上面的迭代解决方案所示,事实函数无法计算高于65(实际上,甚至高于20)的数字的确切阶乘,因为Java内置类型long将溢出。重构事实,所以它将返回一个BigInteger,而不是long将产生精确的结果大输入以及。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值