我创建了一个java程序来计算无穷大:
class up {
public static void up (int n) {
System.out.println (n) ;
up (n+1) ;
}
public static void main (String[] arg) {
up (1) ;
}
}
我实际上没想到它会到达那里,但我注意到的有点好奇的是它每次停在相同的数字:518669
这个号码有什么意义? (或者我想这个数字+1)。
答案 0 :(得分:8)
除了显然518669乘以该方法的堆栈大小等于系统上的总可用堆栈空间之外,该数字本身没什么意义。
答案 1 :(得分:5)
该特定值并不重要,这是您本地设置的结果。你重复获得相同的值是重要且可预测的。
您的程序在此时始终崩溃,因为每次运行程序时,Java虚拟机都会以相同的参数启动,然后执行相同的操作,直到堆栈空间消失。
您可以更改两者,并更改结果。
您可以通过传递-Xss标志来更改JVM可用的最大堆栈大小,例如:
java -Xss4096k MyClass
在我的机器上,使用我的默认启动参数,在10,518次递归调用后,我的堆栈空间不足。我认为我的设置默认值是1024k。
如果我将最大堆栈大小设置为4096k,我可以在堆栈溢出之前获得50,777个递归调用。
您还可以为方法添加更多操作或不同操作,每次调用消耗更多空间并更改可能的调用次数。
如果我在println语句之后将语句MyClass myClass = new MyClass();
添加到代码(每个调用的MyClass的本地实例),那么在溢出之前我可以进行的调用次数从每次调用的10,518次减少到9,709次已存储对MyClass实例的引用。
答案 2 :(得分:2)
您有一个有限的内存分配给调用堆栈。每次运行应用程序时内存量都相同。因此,每次都停止在同一个地方进行计数,因为你已经没有堆栈内存了。
至于你,我会格式化这个mannor
class up
{
public static void up(int n)
{
System.out.println(n);
up(n + 1);
}
public static void main(String[] arg)
{
up(1);
}
}
这样,当您的块开始和结束时,它会更清晰。
答案 3 :(得分:0)
为了回答你的意思,方法的紧密支撑通常与方法的开头对齐。所以在这种情况下,与public
的'p'在同一列中。
答案 4 :(得分:0)
518669没有什么特别的,除了这是你用完之前可以装入你的可用内存的堆栈帧数。
这里没有理由使用递归 - 你应该只使用while循环。