6

我有一个以 x86 模式运行的 C# WinForm 应用程序。它适用于 x86 模式。当我在任何 CPU 模式下运行此应用程序时会出现问题。我收到以下提到的错误:

XXXXXX.dll 中发生了“System.StackOverflowException”类型的未处理异常

我知道这可能是由无限循环引起的,在这种情况下,在 x86 模式下应该会出现同样的错误。我知道这不是因为无限迭代。它与堆栈溢出有关。

在做了一些研究之后,我使用 Editbin 增加了堆栈大小

Editbin.exe /Stack:14000000 "$(TargetDir)MyProject.exe"

Editbin.exe /Stack:14000000 "$(TargetDir)MyProject.exe"

知道可能是什么原因以及我应该采取哪些方向?

4

4 回答 4

37

我的浴缸溢出来了。

试着买一个更大的浴缸。

好的,我做到了。我的浴缸还是溢出来了。

尝试买一个更大的浴缸。

好吧,还是溢出来了!我有一个巨大的浴缸,但它仍然溢出!


如果问题是排水管堵塞并且水龙头开着,那么买一个更大的浴缸也无济于事。

您的问题很可能是您的程序试图消耗无限量的堆栈。使堆栈变大无济于事。

我知道这可能是因为无限循环,在这种情况下,在 x86 模式下应该会出现同样的错误。

这种说法是错误的。不要求发生相同的错误。

为什么它会根据我是否针对特定的 cpu 而有所不同?

抖动可以在不同的场景下生成不同的代码,有时可以生成将无限递归变成无限循环的代码。那些不会消耗无限堆栈,但它们将永远运行。

假设为了论证,没有无限递归。

那么就有可能存在非常的递归。由于 64 位代码可以比等效的 32 位代码占用更多的堆栈空间,因此大递归可能导致堆栈外错误更早发生。

在这种情况下,使堆栈变大是一个坏主意。相反,找到深度递归算法并将其变为迭代算法。

于 2013-03-18T20:11:32.243 回答
7

原因是无限递归。附加调试器并在发生异常时查看堆栈跟踪。

于 2013-03-18T20:08:14.463 回答
3

你得到堆栈溢出的原因仅仅是因为你使用了太多的堆栈。

您仅在 x64 模式而不是 x86 模式下获取它的原因很可能是因为程序在 x64 模式下使用更多堆栈空间,因为引用占用了更多空间。你没有在 x86 模式下得到它只是运气,你根本没有使用足够的堆栈空间来让它在这些特定情况下用完。

解决方案是找出程序中使用如此多堆栈空间的内容。您应该寻找诸如递归函数之类的运行太多级别的东西。一个实现良好的递归函数会使用 10 或 100 级递归,但如果你使用错误的递归,你可能会有 10000000 级递归,这会占用大量堆栈空间。

于 2013-03-18T20:20:23.377 回答
2

您可以查看堆栈跟踪吗?

您可以阅读此属性:Environment.StackTrace。

如果堆栈跟踪超出了您预设的特定阈值,您可以返回该函数。您还可以尝试用循环替换一些递归函数。(如果 .net 2.0 及更高版本,try-catch 块无法捕获 StackOverflowException 对象)

于 2013-03-18T20:11:53.273 回答