安定性のトピック| StackOverflowErrorが一般的な原因と解決策

REVIEW

「StabilityGuideは」圧力試験、故障ドリル、JVM、アプリケーションコンテナ、サービスフレームワーク、トラフィックスケジューリング、監視、診断および他の技術分野のパフォーマンスをカバーし、アリアリエンジニアの共同主催のオープンソースプロジェクトリポジトリよりも揮発性の領域であり、安定性の分野での知識ベースを構築するための、より構造化された方法で、あなたは参加を歓迎します。

@GitHub:github.com/StabilityMa...

各JVMスレッドは、(呼び出された関数のパラメータ、ローカル変数とリターンアドレスなどを含む)現在のスレッドのスタックフレームのJVMを格納するためのプライベートJVMのスレッドスタックを持っています。スレッドは、スレッドのスタック空間が使い果たされている場合は、十分なリソースが新たに作成されたスタックフレームに割り当てられているがないjava.lang.StackOverflowErrorをエラーがスローされます。

どのようにスタックをスレッドに実行していますか?

まず、簡単なプロシージャ・コールのコード例、次のように

public class SimpleExample {
      public static void main(String args[]) {
            a();
      }
      public static void a() {
            int x = 0;
            b();
      }
      public static void b() {
            Car y = new Car();
            c();
      }
      public static void c() {
            float z = 0f;
      }
}
复制代码

main()メソッドが呼び出された後、本方法は、スレッドコードの実行順序、それは、基本データ型、オブジェクトのポインタと、戻り値が個別にプライベートコールスタックに押し込ま、スタックフレームに包まれて実行されて、全体的な実行を実行します下図のように:

まず、プログラムは、main()メソッドスタックを開始します。

次に、スタックのA()メソッドは、変数xは、int型、初期値0として宣言されます。xまたは0の両方がスタックフレームに含まれていることに留意されたいです。

次に、スタックのB()メソッド、カーオブジェクトが作成され、変数yに割り当てられます。実際の車のオブジェクトのみCarオブジェクト参照変数をy、代わりにスレッドスタックのJavaヒープメモリ内に作成され、スタックフレームに含まれていることに注意してください。

最後に、スタックのC()メソッドは、変数zは、float型、初期割り当て0Fとして宣言されます。同様に、Zまたは0Fは、スタックフレームに含まれています。

スタックが空になるまでときに実行する方法は、全てのスレッドのスタックは、LIFOの順にスタックから一つずつフレーム。

どのようにStackOverflowErrorが生成されますか?

上記のように、JVMスレッド・スタックストアドプロシージャは、方法、基本データ型、ローカル変数を実行する値を返す、およびポインタ情報をobjectに、これらのメモリを消費する必要があります。メモリの許容限度を超えて増加したスレッドのスタックサイズと、それはjava.lang.StackOverflowErrorをエラーがスローされます。

無限の再帰呼び出して、次のコードは、最終的にjava.lang.StackOverflowErrorをエラーにつながりました。

public class StackOverflowErrorExample {
      public static void main(String args[]) {
            a();
      }
      public static void a() {
            a();
      }
}
复制代码

この場合には、無限のスタックのA()メソッドは、図に示すように、空乏スレッドスタック領域まで、スタックオーバーフロー。

Exception in thread "main" java.lang.StackOverflowError
    at StackOverflowErrorExample.a(StackOverflowErrorExample.java:10)
    at StackOverflowErrorExample.a(StackOverflowErrorExample.java:10)
    at StackOverflowErrorExample.a(StackOverflowErrorExample.java:10)
    at StackOverflowErrorExample.a(StackOverflowErrorExample.java:10)
    at StackOverflowErrorExample.a(StackOverflowErrorExample.java:10)
    at StackOverflowErrorExample.a(StackOverflowErrorExample.java:10)
    at StackOverflowErrorExample.a(StackOverflowErrorExample.java:10)
    at StackOverflowErrorExample.a(StackOverflowErrorExample.java:10)
    at StackOverflowErrorExample.a(StackOverflowErrorExample.java:10)
复制代码

どのようにStackOverflowErrorを解決するには?

StackOverflowErrorのいくつかの一般的な原因があります。

  • 無限再帰ループコール(最も一般的)。
  • 多くの方法の実装は、スレッドスタックスペースが排出される原因となります。
  • 質量のメソッド内で宣言したローカル変数。
  • ネイティブスタックロジックに割り当てられたコード、およびメモリ要件が小さくない、そのようなjava.net.SocketInputStream.read0スタックに64キロバイト(64 Linuxなど)に割り当てられたバッファを必要とするであろう。

外部手続きエラースローにStackOverflowErrorに加えて、2つの位置決め方法は、スタックオーバーフローがあります。

  • プロセスが突然姿を消したが、クラッシュログを残し、あなたは現在のスレッドのクラッシュログのスタック範囲、およびRSPレジスタの値を確認することができます。値がレジスタスタックRSP範囲外である場合、それはスタックオーバーフローを示します。
  • あなたはログをクラッシュしていない場合は、それだけでコアダンプによって解析されるだろう。jstack $ JAVA_HOME / binに/ Javaのコアによって、次に[PID]。コアを生成し、そしてだろう、ulimitの-c無制限、ときハング・プロセスを実行し、プロセスが実行される前にファイル。[PID]スタックの出力を見てください。長いスレッドのコールスタックがある場合は、通常出力した場合、それが、これはコアコマンドから書類の束をつかむjstackのため、もちろん、何も正常な出力がない場合も、実際に保守エージェントベースの実装がされて見ることができSAながら、いくつかのバージョンでは、そこにバグ。

一般的なソリューションには次のものがあります。

  • コードを修正することで、無限再帰バグを修復したいのか、例外無限の再帰呼び出し、コードの重複行を見つけるためにプログラムスタックによってスローされた例外をスロー。
  • クラス間の循環依存関係のトラブルシューティング。
  • 現在のクラスのインスタンス、及びクラスのクラスインスタンス変数が存在するか否かを調査。
  • スレッドスタックメモリ-Xss JVM起動パラメータを増加させることにより、特定のシナリオでは、適切スレッドスタックスペースの制限を増やすことができ、このとき、例えば、スレッド・スタック2に-Xss2mスペースを配置することにより、通常の使用の多数またはローカル変数の多数を含む方法を実行するために必要メガバイト

次のようにデフォルトのスレッドスタックサイズは、オペレーティングシステム、JVMのバージョン、およびベンダ、共通のデフォルト設定に依存します。

JVMのバージョン デフォルトのスレッドスタックサイズ
SPARC 32ビットJVM 512キロバイト
SPARC 64ビットJVM 1024キロバイト
x86のSolaris / Linuxの32ビットJVM 320キロバイト
x86のSolaris / Linuxの64ビットJVM 1024キロバイト
Windowsの32ビットJVM 320キロバイト
Windowsの64ビットJVM 1024キロバイト

ヒント:実際の生産システム、すぐに対処し、一度発見、StackOverflowErrorが、ログインするための鍵を警告するように設定することができます。

推奨ツール&製品

ARMS - アリクラウドAPM製品は、StackOverflowErrorが異常なキーワードアラートをサポート

参考記事

著者情報:夏、GitHubのID @StabilityMan、海のニックネームのキャリア、アリクラウドARMS&EagleEyeの技術専門家は、2016年にアリババに入社、彼はリンクトラッキングとAPMの監視の診断に関連する仕事に従事してきました。


説明リンク

この記事Yunqiコミュニティのオリジナルコンテンツが許可なく複製することはできません。


おすすめ

転載: juejin.im/post/5d53ca9ef265da03ca11646d