大家好,欢迎来到IT知识分享网。
如何增加Java堆栈的大小?
我问这个问题是为了了解如何在JVM中增加运行时调用堆栈的大小。我已经得到了这个问题的答案,我还得到了许多有用的答案和评论,涉及到Java如何处理需要大型运行时堆栈的情况。我把我的问题和答复的摘要作了补充。
最初,我希望增加jvm堆栈大小,以便像运行这样的程序没有StackOverflowError.public class TT {
public static long fact(int n) {
return n
}
public static void main(String[] args) {
System.out.println(fact(1 <
}}
相应的配置设置是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)
-xss 5米就足够了
fact(1 << 17)
-Xss7m就够了
fact(1 << 18)
-Xss9m就够了
fact(1 << 19)
-Xss 18m就够了
fact(1 << 20)
-Xss35m可以满足
fact(1 << 21)
-Xss68m可以满足
fact(1 << 22)
-Xss129m足以
fact(1 << 23)
-Xss258m足以满足
fact(1 << 24)
-Xss 515米就够了
fact(1 << 25)
从上面的数字来看,Java似乎为上面的函数使用了大约16个字节的堆栈帧,这是合理的。
上面的枚举包含就够了而不是就够了,因为堆栈要求不是确定性的:使用相同的源文件和相同的源文件多次运行它。-Xss…有时成功,有时产生StackOverflowError..例如,1<20,-Xss18m10中的7次就足够了,而且-Xss19m也不总是足够的,但是-Xss20m就够了(总共100次跑完100次)。垃圾收集、JIT启动或其他什么东西会导致这种不确定的行为吗?
中打印的堆栈跟踪。StackOverflowError(也可能在其他例外情况下)只显示运行时堆栈中最新的1024个元素。下面的答案演示了如何计算达到的精确深度(这可能比1024大得多)。
许多响应的人指出,考虑替代的、不太需要堆栈的相同算法的实现是一种好的和安全的编码实践。通常,可以将一组递归函数转换为迭代函数。Stack对象,它在堆上填充,而不是在运行时堆栈上填充)。对于这个特殊的fact功能,很容易转换它。我的迭代版本如下所示:public class TTIterative {
public static long fact(int n) {
if (n
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 <
}}
FYI,正如上面的迭代解决方案所示,fact函数无法计算65以上数字的确切阶乘(实际上,甚至超过20),因为java内建类型long会溢出。重构fact所以它会返回一个BigInteger而不是long对于大量的输入也会产生精确的结果。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/14390.html