我有一个使用深度递归的算法。递归的深度级数会有所不同,具体取决于输入。为避免堆栈溢出异常,我会计算深度并终止于特定深度。
通过一些实验,我之前已经确定500级是停止的点。但是,现在我突然在超过300的级别上获得了堆栈溢出异常。
任何人都可以了解哪些因素会对此产生影响?是吗? CPU和RAM?或者与计算机上正在运行的其他进程有关?
答案 0 :(得分:3)
当你的堆栈空间不足时,你得到一个StackOverflowException
。调用方法使用一些堆栈空间(称为堆栈帧),在该函数期间使用的局部变量也是如此。递归不断添加新的堆栈帧而不会抛弃旧的堆栈帧(除非你采用尾调用优化,C#不能很好地执行)。
因此,究竟何时发生这种情况取决于方法调用的数量以及您在这些方法中所做的事情。
答案 1 :(得分:2)
此解释是针对Java,C,C ++语言的StackOverflowException背后的基本原因。
由于递归方法调用,Stackoverflow异常是由任何语言引起的。
假设您有一个调用自身的方法或无限递归循环的任何其他方法,那么它将导致Stacoverflowexception。这背后的原因是方法调用堆栈被填充,并且它不能容纳任何其他方法调用。
方法调用堆栈看起来像这张图片。
解释 - 假设Main方法有五个语句,第三个方法调用methodA,然后main语句的执行在statement3处暂停,MethosA将被加载到调用堆栈中。然后方法A调用methodB。所以methodB也被加载到堆栈中。
因此,无限递归调用使调用堆栈得到填充。所以它不能再提供任何方法了。所以它抛出了StackOverflowException。
答案 2 :(得分:1)
答案各不相同,请参见此处:Stack capacity in C#
你明智的做法是将你的算法改为不递归,不容易看出你可以递归多少,而且如果你试图预测一个递归深度的certian级别,你的命运基本上是诱人的。那个以及用于堆栈深度的估算算法可能会破坏下一个.NET服务包。