我唯一认为可能会逻辑上引发stackoverflow异常的事情就是如果有人给Jon Skeet点了踩。
但说真的,它是什么?我通过在与第一个类相同的文件中创建另一个类并使用它来调用方法来解决了这个问题。
一般情况下,堆栈溢出异常是由递归算法引起的,其中递归深度超过了(通常)固定的堆栈限制。这通常是算法中的bug导致的,但也可能是因为应用算法的数据结构太“深”。
以下是一个简单的有bug的递归示例(不特定于任何编程语言)。
function int length(list l) {
if (empty(l)) {
return 0;
} else {
return 1 + length(l); // should be 'return 1 + length(tail(l));
}
}
在典型的编程语言中,对于非空列表调用length方法会导致堆栈溢出。即使你修正了这个错误,对于一个很长的列表调用该方法也可能会导致堆栈溢出。
(例外情况是当你使用支持尾递归优化的语言...或更严格地说,编译器时)
堆栈溢出异常是指超出分配的堆栈大小,通常发生在递归调用方法并永远不离开时,也可能由于各种晦涩的方法链引起。问题可能是你的对象中有类似以下代码:
void MyMethod()
{
MyMethod();
}
这些调用会耗尽并永远不会释放使用的堆栈空间,因为调用永远不会结束执行,入口点必须保留。
P.S. SO是为特定的异常命名的(这是基本原理,并不限于.NET),它只是一个开发人员网站的巧妙名称。
StackOverFlows的异常就是它字面意思所表达的,堆栈溢出。通常情况下,这是因为你的方法存在循环依赖关系。例如,方法A调用B,而B又调用A。或者这可能是一个没有基本情况的递归方法。
没有看到代码,不可能知道为什么会出现这种情况,但当线程溢出其调用栈时,就会抛出StackOverflowException
。这通常发生在一个方法无条件递归调用自身而没有条件中断的情况下,从而创建无限递归。由于每次递归都会创建一个新的堆栈帧,因此无限递归理论上将创建无限数量的堆栈帧,我相信你现在可以明白为什么术语“堆栈溢出”是恰当的了。
这通常是由于对一个函数进行递归调用,而该递归调用永远不会终止所导致的。您可能会以几种方式遇到这种情况。一种方式可能是没有基本情况的递归算法,另一种常见的方式是在它们的构造函数中创建相互创建一个A和B对象等。
我建议您通过调试器逐步查找并找出问题 :)
我遇到了这个问题,我注意到我打错了lstEncounter。正如我在C++课上学到的那样,问题在于递归算法基本上使用相同的参数调用自身。我出现错误的示例:
Property Encounter(ByVal N As Integer)
Get
If N < lstEncounters.Count Then
Return Encounter(N)
Else
Return Nothing
End If
End Get
Set(value)
lstEncounters(N) = value
End Set
End Property
简而言之:在递归函数中使用 DirectCast() 和静态绑定(具有类型的变量)以防止 VB 在运行时向堆栈中洪水般地注入数据。
我遇到了一个Stackoverflow错误。 我正在使用一个将1添加到计数器然后重新调用相同例程的例程。 大约每2500到3000个循环,我都会收到stackoverflow错误。 我已经添加了一个DO...Loop来调用该例程,我使用VB Express:
之前:
Public Sub mainloop()
Dim cntr as integer
If cntr >= 5000 ( I just picked a number at random)
me.close ( I close the program)
... (This is where I would manipulate the cntr for diff
results)
cntr = cntr + 1 ( increment the cntr)
mainloop() (re call my loop)
End IF
End Sub
(正如我之前所说,在大约2500-3000后我会遇到Stackoverflow错误)
AFTER:(将此放置在首位执行)
Dim LoopCntr as integer
Do While LoopCntr <= 40000 (this my number.. Use your own number)
If LoopCntr > 40000 Then
Exit Do
End If
mainloop() (The mainloop() has not been changed just the method of calling it)
LoopCntr = LoopCntr + 1
Loop
me.close (When LoopCntr reaches max it closes the program)
在添加了Do..Loop之后,我的程序运行了40000次而没有出现“堆栈溢出”的情况。