2014-02-27 44 views
2

我想知道什么是java.lang.StackOverflowError的根本原因。 我知道它是在递归调用无限次的方法时发生的,但是异常的实际原因是什么以及默认的堆栈大小是多少?java.lang.StackOverflowError的根本原因

+0

粘贴代码.. – Kick

+0

默认大小由VM设置,但您可以使用-Xss JVM参数设置大小。 –

回答

0

只要内存的特定部分(“堆栈”)用完,就会发生stackoverflowerror。基本上你已经耗尽了分配给你的程序的内存,而不需要任何额外的内存,所以你的程序崩溃了。

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

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

然后调用foo(10000)将导致没有无限的计算器。

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

1

只有在递归调用的情况下才会引发它。每当堆栈内存空间填充堆栈中的典型数据时就会抛出:局部变量,本地参数等等。

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

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

0

如果选中doc

时发生堆栈溢出,因为应用程序递归太深而引发。

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

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

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

我只是试图用简单的语言来描述。要知道更深入地检查了许多有用的文章像following

1

的根本原因是这样的:堆栈大小是固定的在运行时,与VM提供没办法,一旦程序运行进行调整。但递归深度不固定,在许多情况下它取决于输入数据。这就是为什么递归深度有时候并不是所有的堆栈帧都适合堆栈的原因。

相关问题