StackOverflowException即使在增加堆栈大小之后
本文关键字:之后 堆栈 增加 StackOverflowException | 更新日期: 2023-09-27 18:04:28
我有一个c# WinForm应用程序,我在x86模式下运行。它在x86模式下工作得很好。当我在任意CPU模式下运行这个应用程序时,问题就出现了。我得到下面提到的错误:
类型为"System"的未处理异常。StackOverflowException'发生在XXXXXX.dll
我知道这可能是由无限循环引起的,但在这种情况下,x86模式下应该发生相同的错误。我知道这不是因为无限迭代。它与堆栈溢出有关。
在做了一些研究之后,我增加了Editbin的堆栈大小
从Editbin.exe/Stack:14000000 "$(TargetDir)MyProject.exe"
Editbin.exe/Stack:14000000 "$(TargetDir)MyProject.exe"
你知道原因是什么吗?我应该往哪个方向走?
我的浴缸溢出水了。
试试换个大一点的浴缸。
好的,我做到了。我的浴缸里还是满是水。
试着弄一个更大的浴缸。
好吧,还是满的!我有一个很大的浴缸,但里面还是满是水!
如果问题是排水管堵塞,水龙头开着,那么买一个更大的浴缸也无济于事。
你的问题很可能是你的程序试图消耗一个无限的堆栈。堆积得更大也无济于事。
我知道这可能是由于无限循环之类的原因,但是在这种情况下,同样的错误应该在x86模式下发生。
这个语句是假的。不要求出现相同的错误。
为什么它是不同的取决于我是否针对一个特定的cpu?
抖动可以在不同的场景下生成不同的代码,有时可以生成将无限递归变为无限循环的代码。它们不会消耗无限的堆栈,但它们会永远运行。
为了论证,假设不存在无界递归。
则有可能存在一个非常大的递归。由于64位代码比等效的32位代码占用更多的堆栈空间,因此大的递归可能导致堆栈外错误更早发生。
在这种情况下,增大堆栈是一个坏主意。相反,找到深度递归算法,并将其转化为迭代算法。
原因是无限递归。附加一个调试器,并在发生异常时查看堆栈跟踪。
堆栈溢出的原因很简单,因为您使用了太多的堆栈。
只在x64模式下而不是在x86模式下得到它的原因很可能是因为程序在x64模式下使用了更多的堆栈空间,因为引用占用了更多的空间。你没有在x86模式下得到它只是运气,你只是没有使用足够的堆栈空间让它在那些特定的情况下运行。
解决方案是找出是什么在你的程序中使用了这么多的堆栈空间。你应该寻找像递归函数这样的东西,它运行的层次太深。一个实现良好的递归函数会使用大约10或100层递归,但如果你使用递归错误,你可能会有10000000层递归,这将使用大量的堆栈空间。
可以查看堆栈跟踪吗?
你可以阅读这个属性:Environment.StackTrace.
如果堆栈跟踪超过了您预设的特定阈值,您可以返回该函数。你也可以尝试用循环代替一些递归函数。(如果。net 2.0及以上版本,StackOverflowException对象不能被try-catch块捕获)