模擬実戦排查堆メモリオーバーフロー(java.lang.OutOfMemoryError:Java heap space)問題


前言:
シミュレーション実戦でスタックメモリオーバーフロー(
JAva.lang.OutOfMemoryError:Java heap space)の質問です.
ヒープメモリオーバーフローの原因:一般的に大量のオブジェクトが作成されており、これらのオブジェクトはずっと参照されており、GCゴミに回収されず、最終的にヒープメモリがいっぱいになり、新しく作成したオブジェクトを格納するのに十分なスペースがない場合、ヒープメモリオーバーフローの問題が発生します.
実際のビジネスシーンではメモリオーバーフローの問題が発生し、調査は一般的に非常に困難で煩雑であり、本稿では簡単な例を組み合わせて調査の具体的な考え方と手順を述べる.
準備:
注意:実際のシーンでは、Linuxサーバに配備されているプロジェクトがメモリオーバーフローの問題を報告するのが一般的です.可能な限り実際のシーンを復元するために、本稿では、メモリオーバーフローをトリガーできるコードを事前に作成し、実行可能なJarパッケージにパッケージ化し、サーバに配置して実行します.
1、メモリオーバーフローの原因となるコードを準備する:
//     Java 
public class OutOfMemory {
    
    private String test;
    
    public OutOfMemory(String test){
        this.test = test;
    }
    
}

//          
public class TestOOM {
    
    public static void main(String[] args) {
        List list = new ArrayList();
        
        while(true){
            /**
             *     OutOfMemory  ,        ,     OutOfMemory     list       ,
             *   GC     ,           
             */
            list.add(new OutOfMemory("5656"));
            System.out.println("5656");
        }
    }
}

コード作成が完了したら、開発ツールを使用してエクスポート
実行可能なJarパッケージ(TestOOM.jar)
2、Linuxサーバーの準備
centosやRed Hatなどをそのまま使えます.
実戦:
1、実行可能なJarパッケージをサーバーに入れて実行する:
①、xshell、xftpツールを使用して、実行可能なJarパッケージ(Jarパッケージ:TestOOM.jar)をサーバーに入れることができる.②、コマンドを使用してJarパッケージを実行する;コマンド:java-Xms 40 m-Xmx 70 m-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=/usr/tmp-jar TestOOM.jar
注意:スタックメモリオーバーフローの発生をできるだけ早くシミュレートするために、Jarパッケージを起動するときに、いくつかのパラメータを設定しました.パラメータ解析:1)、-Xms 40 m初期ヒープサイズ40 m 2)、-Xmx 70 m最大ヒープサイズ70 m 3)、-XX:+HeapDumpOnOutOfMemoryErrorヒープメモリオーバーフローが発生した場合、自動的にヒープメモリdumpスナップショットをエクスポートする4)、-XX:HeapDumpPath=/usr/tmp設定エクスポートされたヒープメモリスナップショットの格納先は/usr/tmp
2、実行に成功した後、JVM監視コマンドを使用してJVMの情報を監視する:
①、jpsコマンド:このコマンドはJavaに関連するプロセスをクエリーし、プロセス番号を出力するために使用されます.次の図は、Jarパッケージが実行されているプロセス番号を示しています.
②、jmapコマンド:jmap-heap 3324このコマンドはプロセス番号が3324のJVMのメモリ情報を検索する.次の図を示します.
図では、スタックメモリの新生代、高齢代のfreeの使用可能なスペースがますます小さくなっていることがわかります.これは、GCゴミ回収が間もなく発生することを示しており、スタックが新しく作成したオブジェクトを格納するためにより多くのスペースを空けることを示しています.
③、jstatコマンド:JVMの性能情報を監視する.たとえば、今回のメモリオーバーフローのトラブルシューティングでは、jstatコマンドを使用してJVMのGCゴミ回収の状況を監視します.コマンド:jstat-gcutil 3324 1000は、プロセス番号3324のJVMのGCゴミ回収を1000ミリ秒ごとに照会することを意味します.次の図を示します.
(1)、YGC(スタック中新生代GC)、FGC(FULL GC)はなぜトリガ頻度がこんなに速いのでしょうか?
答え:スタックメモリのスペースが足りないため、新しく作成したオブジェクトを保存するためにGCゴミ回収でいくつかのスペースを回収する必要があります.
(2)、スタックのメモリ容量が足りない場合、GCは具体的に何が起こるのでしょうか.
回答:
1)、スタックの中の新生代空間が足りない場合、YGC(Minor GCとも呼ばれる)をトリガーし、スタックの中の新生代空間をゴミ回収し、ゴミ回収後に生き残る対象会の中に、対象の
「昇進年齢が「昇進年齢しきい値」に達すると、スタックに移動します.
古い世代のストレージであるため、YGCのたびに、スタック内の古い世代に格納されるオブジェクトの数が増加する可能性があります.
注意:昇進年齢:新生代の対象者がYGCを経験するたびに、昇進年齢に1を加えることを指す.
注意:昇格年齢しきい値:SerialとParNew GCの2つの回収器で、「昇格年齢しきい値」はパラメータMaxTenuringThresholdで設定でき、デフォルト値は15です.
上の「昇進年齢」は次のとおりです.
実例からJavaアプリケーションのGC最適化について
2)、スタックの新生代にYGCが発生しようとすると、新生代で生き残ったオブジェクトのうち「昇進年齢閾値」に達したオブジェクトが占有するスペースが、スタックの中年世代の残りの利用可能なスペースよりも大きいことが判明すると、YGCを直接行わずにFGCをトリガし、FULL GCはスタック全体(新生代、旧世代)注意:FULL GCは主に2つのステップに分けられ、まず堆積中の古い年代に対してごみ回収(Major GCとも呼ばれる)を行い、その後、堆積中の新生代に対してごみ回収(YGC)を行う.
拡張:ヒープの構造図:
3、メモリオーバーフローが発生すると、自動的にスナップショットが生成され、スタックメモリスナップショットを分析する.
①、XFTPなどのツールを使ってサーバーの中のスナップショットファイルをエクスポートして、本文のメモリスナップショットファイルはhprofを接尾辞とするファイルである;スナップショットファイルをエクスポートした後、JDKが持っているjvisualvm.exe分析ツールを通じて開けて分析することができる.
jvisualvm.exeはどこですか?(windowsシステムを例に)
それは
JDKのインストールディレクトリのbinディレクトリの下にあります.
図:
②、jvisualvm.exeを使用してスナップショットファイルをインポートする.図:(1)、
スタックメモリスナップショットを分析した結果:
(3)の図面を見ると、スタックメモリのインスタンスオブジェクトの割合は99.9%であり、このインスタンスオブジェクトの大量作成によるスタックメモリのオーバーフローであると判断できる.
そういえば、スタックメモリのオーバーフローをトリガーできる独自のプログラムを振り返ってみると、
While(true)デッドサイクルでOutOfMemoryオブジェクトがワイヤレスで作成され、スタックメモリ領域が消費されます.
締めくくり:
上記の実戦の小さな例を通して、スタックメモリのオーバーフローが発生した場合の調査手順を大体理解することができますが、実際のシーンでは、このような状況はより複雑で変化する可能性があります.
たとえば、上記の例では、スタックメモリオーバーフロー時に自動的に生成されるスタックメモリスナップショットファイルのサイズが100 m以上に達しています.実際のシーンでは、これが非常に大きい可能性があります.この場合、スナップショット分析ツールがスタック内のスナップショットをインポートできない可能性があります.そのため、将来的に問題が発生するには、普段から勉強を続けなければなりません.プログラマーはコードを書くだけでなく、問題を解決する能力も必要です.
❤あなたの学习の足迹を残しておくことを忘れないでください
すべての文章を読んでほめないのはすべて“ごろつき”で、へへへヾ(◍°∇°◍)ノ!冗談を言って、あなたの小さい手を動かして、ほめて終わって、あなたのすべての人は1部の力(ほめ+評論)を出してもっと多くの学習者を参加させます!とても感謝します!̄ω ̄=