6

x86 モードで実行している C# WinForm アプリケーションがあります。x86モードでうまく機能します。このアプリケーションを任意の CPU モードで実行すると、問題が発生します。以下のエラーが表示されます。

タイプ 'System.StackOverflowException' の未処理の例外が XXXXXX.dll で発生しました

これは無限ループが原因である可能性があり、その場合、x86モードで同じエラーが発生するはずです。これは無限の反復によるものではないことを私は知っています。スタックオーバーフローと関係があります。

いくつかの調査を行った後、Editbinでスタックサイズを増やしました

から

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

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

何が原因で、どの方向に進むべきか考えていますか?

4

4 に答える 4

37

浴槽があふれています。

より大きな浴槽を手に入れてみてください。

はい、やりました。私の浴槽はまだあふれています。

さらに大きな浴槽を手に入れてみてください。

OK、まだあふれています!私は巨大な浴槽を持っていますが、それはまだ溢れています!


問題が排水管が詰まっていて蛇口がオンになっていることである場合、より大きな浴槽を手に入れることは役に立ちません。

問題は、プログラムが無限の量のスタックを消費しようとしている可能性があります。スタックを大きくしても効果はありません。

これは無限ループが原因である可能性がありますが、その場合はx86モードでも同じエラーが発生するはずです。

このステートメントは誤りです。同じエラーが発生する必要はありません。

特定のCPUをターゲットにしているかどうかによって異なるのはなぜですか?

ジッタは、さまざまなシナリオでさまざまなコードを生成する可能性があり、場合によっては、無限再帰を無限ループに変えるコードを生成する可能性があります。それらは無限のスタックを消費しませんが、永久に実行されます。

議論のために、無制限の再帰がないと仮定します。

その場合、非常に大きな再帰が発生する可能性があります。64ビットコードは同等の32ビットコードよりも多くのスタックスペースを増やす可能性があるため、再帰が大きいと、スタック外エラーが早期に発生する可能性があります。

その場合、スタックを大きくすることはお勧めできません。代わりに、深く再帰的なアルゴリズムを見つけて、それを反復アルゴリズムにします。

于 2013-03-18T20:11:32.243 に答える
3

スタックオーバーフローが発生する理由は、単にスタックを使いすぎているためです。

x86モードではなく、x64モードでのみ取得する理由は、参照がより多くのスペースを使用するため、プログラムがx64モードでより多くのスタックスペースを使用するためである可能性があります。x86モードで取得できないのは幸運なことです。特定の状況でスタックが不足するほど、スタックスペースを十分に使用していません。

解決策は、非常に多くのスタックスペースを使用しているのがプログラム内にあるかどうかを調べることです。深すぎるレベルで実行される再帰関数のようなものを探す必要があります。適切に実装された再帰関数は、10または100レベルの再帰を使用しますが、再帰を間違って使用している場合は、10000000レベルの再帰が発生する可能性があり、多くのスタックスペースが使用されます。

于 2013-03-18T20:20:23.377 に答える
2

スタックトレースを表示できますか?

このプロパティを読み取ることができます:Environment.StackTrace。

スタックトレースが事前設定した特定のしきい値を超えた場合は、関数を返すことができます。一部の再帰関数をループに置き換えることもできます。(.net 2.0以降の場合、StackOverflowExceptionオブジェクトはtry-catchブロックでキャッチできません)

于 2013-03-18T20:11:53.273 に答える