为什么在518669之后会出现堆栈溢出错误?

时间:2010-03-08 21:10:39

标签: java numbers stack-overflow

我创建了一个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)。

5 个答案:

答案 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循环。