無限再帰ループを防ぐため、JVMにはネストされたスタックフレーム(関数呼び出しに最も関連する構造体)が多すぎるかどうかを確認するビルトインチェックがあります。
例外がスローされると、元のスタックフレームから上位のスタックフレームに移動するときに、JVMは例外にメモを追加します(これは自動的に舞台裏で行われます)。行番号テーブルが使用可能な場合、例外をスローした操作に関連付けられている行番号は何か。
例外がキャッチされることがあります。この場合、移動したフレームについてのこの情報は決して使用されません(誰も分かりませんが、おそらくこれまで生成されていない可能性もあります) )、最上位に到達すると印刷され、印刷ルーチンは例外の格納された移動経路を調べる方法を認識しており、現在一般的に予想されているようにそれらを印刷します。
通常、再帰ルーチンは許可されたスタックフレームスタックよりも深く移動するので、スタックフレームに依存しないように再帰を書き直す必要があります。あなたが必要とする深さをサポートしていません。これを行うには、通常、スタックフレームのさまざまなレベルに格納されるデータを取り出し、それらを「オブジェクトのようなフレーム」に配置します。これはフレーム内ではなくオブジェクト内にあるので、フレーム深度に制限されなくなりました。使用可能なヒープメモリに制限されています。
これは、ヒープストアドスタックで開始するアルゴリズムを書き直す必要があることを意味します。次に、再帰的メソッドと同じ方法で正しいコンテキストをプッシュしてポップする必要があります。
オールインオールではそれほど難しいことではありませんが、あなたが最初にやっているのであれば、それはよく知られていないように見えます。
another questionから借りて、それを少し凝縮して、あなたはこれが効果的にあなたがする同じスタックフレームを使用できるようになります
algorithm search(NODE):
createStack()
addNodeToStack(NODE)
while(stackHasElements)
NODE = popNodeFromStack()
doSomethingWith(NODE)
for each node CHILD connected to NODE:
addNodeToStack(CHILD)
に
algorithm search(NODE):
doSomethingWith(NODE)
for each node CHILD connected to NODE:
search(CHILD)
よう的アルゴリズムを変換しますその再帰呼び出しをヒープ上にプッシュすることによって、再帰呼び出し全体を処理します。
スタックトレースに表示される例外は、発生した瞬間に印刷されるべきです。 –
StackOverflowが検出されるまでにスタックトレースがどれだけ深い関数呼び出しを必要としているか尋ねていますか? –
スタックフレームの構築中にオーバーフローが発生すると思います。つまり、メソッド呼び出しの試行中に、そのメソッド内のコードが実行を開始する前に実行されます。 – markspace