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