Java StackOverflowError
-
Java の
java.lang.StackOverflowError
-
java.lang.StackOverflowError
の原因 -
Java での
java.lang.StackOverflowError
の解決策
この記事では、Java プログラムの main()
メソッドで発生する java.lang.StackOverflowError
エラーの考えられる原因に取り組みます。
Java の java.lang.StackOverflowError
java.lang.StackOverflowError
は Java でスローされ、特に深い再帰によりアプリケーションのスタックが使い果たされたことを通知します。 java.lang.StackOverflowError
クラスは VirtualMachineError
クラスの拡張であり、JVM
が誤動作しているか、すべてのリソースを使い果たして機能できないことを通知します。
java.lang.StackOverflowError
の原因
java.lang.StackOverflowError
とそれが発生する理由を理解するための例を見てみましょう。
最初にサンプル クラスに main メソッドを含めます。 その後、メインメソッド内で再帰的に呼び出される RecursiveFunction()
という名前の関数を作成します。
RecursiveFunction()
関数では、各呼び出しの後に 1
のインクリメントを追加して数値を表示します。
完全なソース コード:
public class example {
static int z;
public static int RecursiveFunction(int e) {
z = z + 1;
System.out.println(" Number is : " + z);
return z + RecursiveFunction(z + 1);
}
public static void main(String[] args) {
example.RecursiveFunction(z);
}
}
以下に示すような同様の結果が得られます。
出力:
Exception in thread “main” java.lang.StackOverflowError
at java.io.PrintStream.write(Unknown Source)
at java.io.PrintStream.print(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at StackOverflowErrorClass.RecursiveFunction(StackOverflowErrorClass.java:7)
at StackOverflowErrorClass.RecursiveFunction(StackOverflowErrorClass.java:8)
at StackOverflowErrorClass.RecursiveFunction(StackOverflowErrorClass.java:8)
.
.
.
java.lang.StackOverflowError
を引き起こすサンプルプログラムの問題について話しましょう。
スレッド
のスタックが、スレッド
がそれらを実行している間、メソッド、プリミティブデータ型
、変数
、オブジェクト参照
、および戻り値
の値が格納される場所である例について説明しました。 それらはすべてメモリを使用しています。スレッド
のスタックサイズが割り当てられたメモリの最大量を超えるポイントまで増加すると、java.lang.StackOverflowError
がトリガーされます。Main()
メソッドは、このプログラムでRecursiveFunction()
関数を呼び出します。RecursiveFunction()
メソッドは繰り返し自身を呼び出し、この実装により無限に呼び出されます。
これが発生すると、RecursiveFunction()
メソッドの呼び出し回数に制限はありません。 スレッド
のスタック サイズの制限は、数百回または数千回の反復後に超えられます。
説明したコードは数字を出力しますが、それを終了させる条件はありません。 これがjava.lang.StackOverflowError
の原因であり、スタックのサイズが完全に使い果たされ、それ以上拡張できないことを示します。
Java での java.lang.StackOverflowError
の解決策
以下は、java.lang.StackOverflowError
例外の可能な解決策です。
再帰的な行を見つける
thread
スタックを適切に分析し、発生し続ける線のパターンを探す必要があります。 これらの行は、再帰的に呼び出されるコードを指しています。
これらの行を見つけたら、コードを包括的に分析して、再帰が決して終わらないかどうかを判断する必要があります。
スレッドサイズを大きくする
Thread
スタックのサイズを増やして、より多くのコマンド用のスペースを確保するという選択肢があります。 コンパイラのパラメータを変更すると、Thread
スタックの最大サイズを増やすことができます。
終了条件
同じ呼び出しが繰り返し行われないようにするには、再帰呼び出しが確実に終了するように、正しい終了条件またはその他の条件を実装するように努力する必要があります。
次のコード例で発生した問題を修正するために、終了条件を追加しましょう。 z
が 19
に達するたびに if
ステートメントを使用してチェックします。 関数を終了します。
if (z == 19)
return z;
完全なソース コード:
public class example {
static int z;
public static int RecursiveFunction(int e) {
z = z + 1;
System.out.println(" Number is : " + z);
if (z == 19)
return z;
return z + RecursiveFunction(z + 1);
}
public static void main(String[] args) {
example.RecursiveFunction(z);
}
}
出力:
Number is : 1
Number is : 2
Number is : 3
Number is : 4
Number is : 5
Number is : 6
Number is : 7
Number is : 8
Number is : 9
Number is : 10
Number is : 11
Number is : 12
Number is : 13
Number is : 14
Number is : 15
Number is : 16
Number is : 17
Number is : 18
Number is : 19
I have been working as a Flutter app developer for a year now. Firebase and SQLite have been crucial in the development of my android apps. I have experience with C#, Windows Form Based C#, C, Java, PHP on WampServer, and HTML/CSS on MYSQL, and I have authored articles on their theory and issue solving. I'm a senior in an undergraduate program for a bachelor's degree in Information Technology.
LinkedIn