java.lang.StackOverflowError的根本原因

时间:2014-02-27 11:40:04

标签: java recursion stack-overflow

我想知道java.lang.StackOverflowError的根本原因是什么。 我知道当方法被递归地称为无限次时会发生这种情况但是异常的实际原因是什么以及默认的堆栈大小是什么?

4 个答案:

答案 0 :(得分:1)

仅在递归调用的情况下不一定抛出它。只要堆栈内存空间填充了堆栈上的典型数据,就会抛出它:局部变量,本地参数等等。

显然,获得堆栈溢出错误的可能性随着堆栈的大小(正在执行的当前方法和线程的根之间存在多少方法调用)以及活动线程的数量而增加。 p>

但是,正如我所提到的,递归调用并不是获得大堆栈的唯一原因。

答案 1 :(得分:1)

根本原因是:堆栈大小在运行时是固定的,并且一旦程序运行,VM就无法调整它。但递归深度不固定,在很多情况下它取决于输入数据。这就是为什么递归深度有时使得并非所有堆栈帧都适合堆栈。

答案 2 :(得分:0)

只要内存的特定部分(“堆栈”)用完,就会发生stackoverflower错误。基本上你已经没有分配给你的程序的内存,而没有要求任何额外的内存,所以你的程序崩溃。

具体来说,堆栈用于与调用函数和线程相关的所有事情,因此理论上你甚至可以通过创建一个新线程来耗尽内存(尽管你首先需要用函数调用来填充它)。另外,递归不需要非常大。

public int foo(int i){
    if (i=0)
       return 0;
    return (foo(i-1)+foo(i-1)%1000);
}

然后调用foo(10000)将导致stackoverflow不是无限的。

如果您对查找堆栈更感兴趣,我会建议递归如何在更低级别的语言中工作,例如汇编,您可以真正看到您的机器在做什么(注意学习这将需要相当多的负担得起,但会让你成为一个更好的程序员。)

答案 3 :(得分:0)

如果您查看doc

  

当由于应用程序过于冗长而发生堆栈溢出时抛出。

现在..要知道为什么递归方法调用正在创建此错误,您应该知道java中方法调用的机制。

用简单的句子来描述,当一个方法被调用时,方法调用的信息被推入内存中的一个堆栈中。当方法结束意味着返回时,则弹出信息。堆栈大小不是无限制的,所以当内存溢出并且你试图调用另一个方法(即推送另一个方法调用的信息)时,它会抛出这个错误。

现在对于无限递归方法调用,你只是推入堆栈,但由于方法没有完成,所以你不会弹出。所以肯定会出现上述情况..

我试着用简单的语言描述。要更深入地了解许多有用的文章,例如following