2

巡回セールスマンの問題 (時間消費、状態の視覚的表現など) を解決する際に、さまざまなアルゴリズムがどのように機能するかを確認できる学生向けの教育プログラムを作成しています。問題は、良いアルゴリズムだけでなく、悪いアルゴリズムも示さなければならないことです。たとえば、TSP (恐ろしい選択) の幅優先探索アルゴリズムを実装します。

プログラム自体はJavaで書かれています。問題解決アルゴリズム用に別のスレッドがあり、すべてのアルゴリズムは特定のインターフェイスを実装しているため、各反復後に干渉できます。

N 個のノード (n = 都市の数) を持つツリー構造で実行されるすべてのブラインド サーチ アルゴリズムで、各ノードは N 個の要素の配列であり、その実装は約 50k ノードを生成した後に StackOverFlow Exception を生成します。限られた量の都市を使用できるように、ユーザー インターフェイスを制限したくありません。シミュレートされたアニールは、何千もの都市で機能します。

質問は次のとおりです。システムがクラッシュしようとしている時点を特定できるように、指定された論理ステートメントで使用できる信頼できる関数はありますか? 何かがスタイルです: if (System.memoryLeft() <= 100 / bytes / ) { // 作業を停止し、アクションを実行します

前もって感謝します。

4

2 に答える 2

2

エラーがスローされることを検出する最も簡単な方法は、エラーがスローされるまで待機してキャッチすることです。

try {
   action();
} catch(StackOverflowError ste) {
   // you can't call anything here safely, but you can return or unwind the stack.
}

注: 最大スタック サイズはマシンによって異なり、コマンド ラインの設定に基づいています。通話回数によるものではありません。

この問題が本当に心配な場合は、コードを変更して再帰を使用せず、この問題を完全に回避することをお勧めします。


問題は、表示/記録されるスタックの最大深度が 1024 であることです。スタックが長い場合、元の原因がわかりません。できることは、最大スタック サイズを(JVM で許可されている場合はそれ以下に)減らし-Xss128kて、スタック トレースが常に十分に短くキャプチャされるようにすることです。

public static void main(String... ignored) {
    callMe(1);
}

private static void callMe(int i) {
    callMe(i);
}

より小さいスタック サイズで呼び出された場合

at Main.callMe(Main.java:42)
at Main.callMe(Main.java:42)
at Main.callMe(Main.java:42)

many deleted

at Main.callMe(Main.java:42)
at Main.callMe(Main.java:42)
at Main.callMe(Main.java:42)
at Main.main(Main.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
于 2013-04-25T08:09:02.023 に答える
1

私の答えにリンクしてください。C#、C++、および Java でスタック オーバーフローを引き起こす最も簡単な方法

この説明は、java、C、C++ 言語の StackOverflowException の背後にある基本的な理由です。

Stackoverflow 例外は、再帰的なメソッド呼び出しが原因で、一般的にどの言語でも発生します。

無限再帰ループのためにそれ自体または他のメソッドを呼び出すメソッドがあると仮定すると、Stacoverflowexception が発生します。この背後にある理由は、メソッド呼び出しスタックがファイルされ、他のメソッド呼び出しに対応できないためです。

メソッド呼び出しスタックはこの図のようになります。

ここに画像の説明を入力

説明-- Main メソッドに 5 つのステートメントがあり、3 番目のメソッドに methodA の呼び出しがあるとします。この場合、main メソッドの実行は statement3 で一時停止され、MethosA が呼び出しスタックにロードされます。次に、メソッド A が methodB を呼び出します。したがって、methodB もスタックにロードされます。

したがって、このように無限再帰呼び出しを行うと、コール スタックがいっぱいになります。したがって、これ以上の方法はありません。そのため、StackOverflowException がスローされます。

そして、それに遭遇する方法は、このリンクを参照してください

StackOverflowException をチェックするためのメソッド呼び出しスタック サイズの計算

このクエリの解決策も探しています。

于 2013-04-25T08:04:48.893 に答える