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就足够了 fact(1 << 15)

-Xss5m足够了 fact(1 << 17)

-Xss7m足够了 fact(1 << 18)

-Xss9m就足够了 fact(1 << 19)

-Xss18m足够了 fact(1 << 20)

-Xss35m就足够了 fact(1 << 21)

-Xss68m就足够了 fact(1 << 22)

-Xss129m就足够了 fact(1 << 23)

-Xss258m就足够了 fact(1 << 24)

-Xss515m就足够了 fact(1 << 25)

从上面的数字来看,似乎Java每个堆栈帧使用大约16个字节用于上述函数,这是合理的.

上面的枚举可以是足够的,而不是足够的,因为堆栈需求不是确定性的:使用相同的源文件多次运行它,并且-Xss...有时成功,有时会产生一个StackOverflowError.例如,对于1 << 20,-Xss18m在10次中有7次运行就足够了,并且-Xss19m总是不够,但-Xss20m足够了(在所有100次100次中).垃圾收集,JIT踢入或其他什么导致这种不确定行为?

打印在a处的堆栈跟踪StackOverflowError(以及可能的其他例外)仅显示运行时堆栈的最新1024个元素.下面的答案演示了如何计算达到的确切深度(可能比1024大得多).

许多回复的人都指出,考虑使用相同算法的替代的,更少堆栈的实现,这是一种安全的编码实践.通常,可以将一组递归函数转换为迭代函数(使用例如Stack对象,它在堆上而不是在运行时堆栈上填充).对于这个特殊的fact功能,转换它很容易.我的迭代版本看起来像:

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));

}

}

仅供参考,正如上面的迭代解决方案所示,该fact函数无法计算65以上(实际上甚至超过20)的数字的精确因子,因为Java内置类型long会溢出.重构fact所以它将返回a BigInteger而不是long会产生大输入的精确结果.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值