JVM パート 2: パフォーマンスの監視とチューニング_05_GC ログの分析_シリコン バレー

01-GC ログ パラメータ

パラメータ 例証する
-verbose:gc gcログ情報を出力、デフォルトで標準出力に出力
-XX:+PrintGC GC ログを出力します。類似: -verbose:gc
-XX:+PrintGCDetails ガベージコレクションが発生したときにメモリ回復のログを出力し、
プロセスが終了したときに現在のメモリ領域の割り当てを出力します
-XX:+PrintGCTimeStamps GC発生時のタイムスタンプを出力する
-XX:+PrintGCDateStamps GC が発生したときのタイムスタンプを出力します (日付の形式で、例: 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 各 GC の前後にヒープ情報を出力する
-Xloggc: GC ログが標準出力に出力されるのではなく、ファイルに書き込まれることを示します

02-GC ログ形式

レビュー: GC 分類

HotSpot VM の実装では、その中の GC はリカバリ領域に応じて 2 つのタイプに分けられます。1 つは部分コレクション (Partial GC) で、もう 1 つは全ヒープ コレクション (Full GC) です。

  • 部分的なコレクション: Java ヒープ全体を完全には収集しないガベージ コレクション。次のように分類されます。
    • Young GC (Minor GC / Young GC): 新世代のガベージ コレクションのみ (Eden\S0,S1)
    • 古い世代のコレクション (Minor GC / Old GC): 古い世代のガベージ コレクションです。
      • 現在、古い世代を個別に収集する動作を持つのは CMS GC だけです。
      • メジャー GC はフル GC と混同されることが多く、オールド エイジ コレクションかフル ヒープ コレクションかを明確に区別する必要があることに注意してください。
    • 混合コレクション (Mixed GC): 新しい世代全体と古い世代のガベージ コレクションの一部を収集します。
      • 現在、G1 GC のみがこの動作をしています。
  • フル ヒープ コレクション (フル GC): Java ヒープおよびメソッド領域全体を収集するガベージ コレクション。

フル GC がトリガーされるのはどのような状況ですか?

  • 古い世代のスペース不足
  • メソッドがスペースを超える
  • System.gc() を明示的に呼び出す
  • 古い時代にマイナー GC が入力するデータの平均サイズは、古い時代に利用可能なメモリよりも大きい
  • 大きなオブジェクトは古い世代に直接行き、古い世代には十分な空き容量がありません

さまざまな GC クラスの GC の詳細

/**
 *  -XX:+PrintCommandLineFlags
 *
 *  -XX:+UseSerialGC:表明新生代使用Serial GC ,同时老年代使用Serial Old GC
 *
 *  -XX:+UseParNewGC:标明新生代使用ParNew GC
 *
 *  -XX:+UseParallelGC:表明新生代使用Parallel GC
 *  -XX:+UseParallelOldGC : 表明老年代使用 Parallel Old GC
 *  说明:二者可以相互激活
 */
public class GCUseTest {
    
    
    public static void main(String[] args) {
    
    
        ArrayList<byte[]> list = new ArrayList<>();

        while(true){
    
    
            byte[] arr = new byte[1024 * 10];//10kb
            list.add(arr);
//            try {
    
    
//                Thread.sleep(5);
//            } catch (InterruptedException e) {
    
    
//                e.printStackTrace();
//            }
        }
    }
} 

GC ログ分類

マイナー GC

[GC (Allocation Failure) [PSYoungGen: 131072K->21486K(152576K)] 131072K->125625K(500736K), 0.0264772 secs] [Times: user=0.05 sys=0.34, real=0.03 secs] 

画像-20221023001250518

法:

【名称:GC前のメモリ使用量→GC後のメモリ使用量(この領域の合計メモリサイズ)】

フルGC

[Full GC (Ergonomics) [PSYoungGen: 21491K->0K(283648K)] [ParOldGen: 234962K->255123K(543744K)] 256454K->255123K(827392K), [Metaspace: 2941K->2941K(1056768K)], 0.0377849 secs] [Times: user=0.45 sys=0.00, real=0.04 secs] 

画像-20221022232846310

法:

【名称:GC前のメモリ使用量→GC後のメモリ使用量(この領域の合計メモリサイズ)】

ログ構造の分析

ガベージコレクター

  • Serial Collector を使用した新しい世代の名前は Defual New Generation であるため、表示は「[DefNew]」です。
  • ParNew コレクターを使用すると、新しい世代の名前は "[ParNew" になります。これは、"Parallel New Generation" を意味します。
  • Parallel Scavenge コレクターを使用する新しい世代の名前は「[PSYoungGen」で、ここの JDK1.7 は PSYoungGen を使用します。
  • Parallel Old Generation コレクタを使用する古い世代の名前は「[ParOldGen」です。
  • G1 コレクターを使用すると、「ガベージ ファースト ヒープ」と表示されます。

割り当て失敗

今回の GC の理由は、新しいデータを格納するための十分なスペースが若い世代にないためであることを示しています。

GC前後

前の図から、GC ログの一般的な法則は、GC 前のメモリ使用量 -> GC 後のメモリ使用量 (この領域の合計メモリ サイズ) であることがわかりました。

[PSYoungGen: 16302K->2044K(18432K)] 16302K->15130K(59392K), 0.0033553 secs]

角括弧内: GC Husi 後の若い世代のヒープのサイズ、リサイクル後のサイズ (若い世代のヒープの合計サイズ)

括弧外:GC回復前の若い世代と古い世代のサイズ、回復後のサイズ(若い世代と古い世代の合計サイズ)

GC 時間

GC ログには、user、sys、real の 3 回があります。

  • user - ユーザーランドコードを実行するプロセスに費やされた時間 (カーネルの外部)。これは、このプロセスの実行に使用された実際の CPU 時間です。他のプロセスと、このプロセスによってブロックされた時間は含まれません。ガベージ コレクションの場合は、GC スレッドの実行によって使用された合計 CPU 時間を示します。
  • sys - プロセスがカーネル モードで費やしたクロック時間。つまり、カーネルがシステムコールの実行またはシステム時間の待機に使用する CPU 時間です。
  • real - この時間には、他のプロセスによって使用されるタイム スライスと、プロセスがブロックされている時間 (I/O の完了の待機など) が含まれます。並列 GC の場合、この数値は (ユーザー時間 + システム時間) をガベージ コレクターが使用するスレッド数で割った値に近くなるはずです。

マルチコアの理由により、一般的な GC イベントでは、リアルタイムは sys + ユーザー時間よりも短くなります。これは、通常、複数のスレッドが同時に GC を実行するため、リアルタイムは sys + ユーザー時間よりも短くなります。real > sys + user の場合、アプリケーションに次の問題がある可能性があります: IO 負荷が非常に重要であるか、CPU が十分ではありません。

マイナー GC ログの解析

画像-20221015210100631

2020-11-20T17:19:43.265-0800

2013-05-04T21:53:59.234+0800
などの-XX:+PrintGCDateStamps パラメーター ログ印刷時刻と日付形式を追加します。

0.822:

-XX:+PrintGCTimeStamps パラメータ
gc が発生したときに、Java 仮想マシンが起動してからの秒数を追加します。

[GC(割り当て失敗)

マイナー GC であるガベージ コレクションが発生します。新しい世代と古い世代の GC を区別しません。括弧内の内容は GC の理由です。ここでの割り当て失敗の理由は、必要なデータを格納するのに十分な領域が新しい世代にないためです。割り当てられ、失敗します。

[PSYoungGen:76800K->8433K(89600K)

PSYoungGen: GC が発生する地域を示し、地域名は使用される GC コレクターと密接に関連しています。

  • シリアルコレクター: デフォルトの新世代は Defnew を示しています
  • ParNew コレクター: ParNew
  • Parallel Scanvenge コレクター: PSYoung
  • 古い世代は新しい世代と同じで、コレクターの名前にも関係しています。

76800K→8433K(89600K):GC前のメモリ領域の使用容量→GC後のカバー領域の容量(この領域の総容量)

  • 新世代の場合、合計容量は新世代メモリ全体の 9/10、つまり eden+from/to 領域を表示します。
  • 旧世代なら総容量は本体メモリのサイズ、変わらない

76800K→8449K(294400K)

今回はマイナー GC ですが、新しい世代のガベージのみを収集しますが、ヒープの総容量に関する情報を確実に出力します。

領域容量GCが表示された後、ヒープメモリ領域全体のGCが表示され、GC前のヒープメモリの使用容量→GC後のヒープメモリ容量(ヒープメモリの総容量)と合計ヒープ メモリの容量 = 9/10 新世代 + 古い世代の場合、ヒープ メモリの合計容量は、初期化されたメモリ サイズよりも少なくなければなりません。

,0.0088371

GC 全体で費やされた時間 (秒単位)

[時間:user=0.02 sys=0.01,real=0.01 秒]

  • user: CPU がユーザーモードで作業するのに費やした時間を指します
  • sys: カーネル モードで動作している CPU によって費やされた時間を指します
  • real: このイベントに費やされた合計時間を指します

完全な GC ログ分析

画像-20221015205712560

2020-11-20T17:19:43.794-0800

-XX:+PrintGCDateStamps パラメータを追加

ログの印刷日時の形式は
2013-05-04T21:53:59.234+0800です。

1.351

このパラメーターに -XX:+PrintGCTimeStamps を追加します

gc が発生したときに Java 仮想マシンが起動されてから経過した秒数

フル GC (メタデータ GC しきい値)

括弧は gc が発生する理由です。理由: メタスペース領域が十分ではありません。さらに、次のように、フル GC
を引き起こす他の 2 つの状況があります



[PSYoungGen: 100082K->0K(89600K)]

PSYoungGen: GC が発生する地域を示し、地域名は使用される GC コレクターと密接に関連しています。

  • シリアルコレクター: デフォルトの新世代ディスプレイ DefNew
  • ParNew コレクター: ParNew
  • Parallel Scanvenge コレクター: PSYoungGen
  • 古い世代は新しい世代と同じで、コレクターの名前にも関係しています。

10082K→0K(89600K):GC前のこのメモリ領域の使用容量→GC用のこの領域の容量(この領域の総容量)

  • 新世代の場合、合計容量は新世代メモリ全体の 9/10、つまり eden+from/to 領域を表示します。
  • 旧世代なら総容量はメモリ全体のサイズ、変わらない

ParOldGen:32K->9638K(204800K)

古い領域には GC がないため、この GC はメタスペースが原因です

10114K→9638K(294400K)、

領域容量GCが表示された後、ヒープメモリ領域全体のGCが表示され、GC前のヒープメモリの使用容量→GC後のヒープメモリ容量(ヒープメモリの総容量)と合計ヒープ メモリの容量 = 9/10 新世代 + 古い世代の場合、ヒープ メモリの合計容量は、初期化されたメモリ サイズよりも少なくなければなりません。

[ミートスペース:20158K->20156K(1067008K)]、

Metaspace GC は 2K スペースを再利用します

03-GCログ解析ツール

以上、GCログの出力と意味を紹介しましたが、GCログは面倒くさそうなので、GCログの可視化解析ツールGCeasyとGCviewerを紹介します。GCログ可視化分析ツールにより、JVMの各世代のメモリ使用量、ガベージコレクションの回数、ガベージコレクションの理由、ガベージコレクションの占有時間、スループットが簡単にわかる場合に役立ちます。良いです。

GC ログをファイルに保存する場合は、次のパラメーターです。

-Xloggc:/path/to/gc.log

次に、スペースを使用してこれらの gc ログを分析できます。

GCeasy (より実用的)

URL: https://gceasy.io/

GCeasy はオンラインの GC ログ アナライザーであり、GC ログの分析、メモリ リークのチェック、GC 中断の理由の分析、および JVM 構成の提案の最適化を行うことができます。そして、それは無料で試すことができます。

GCViewer(メンテナンス終了)

上はオンラインGCログアナライザー、下はオフライン版GCViewerを紹介

GCViewer は、SUN/Oracle、IBM、HP、および BEA Java 仮想マシンによって生成されたガベージ コレクター ログを視覚化するための無料のオープン ソース分析ツールです。

GCViewer は、Java VM オプション -verbose:gc および .NET -Xloggc: によって生成されたデータを視覚化するために使用されます。また、ガベージ コレクションに関連するパフォーマンス メトリック (一時停止の累積スループット、最長一時停止など) も計算します。この機能は、世代サイズを変更したり、初期ヒープ サイズを設定したりして、アプリケーションのガベージを調整する場合に役立ちます。

ダウンロードリンク: https://github.com/chewiebug/GCViewer/wiki/Changelog

使用

ダブルクリックまたは java -jar gcviewer-1.37-SNAPSHOT.jar

その他のツール (無視できます)

Gチスト

  • GChistoはGCログを専門的に分析するためのツールで、GCログを通じてMinorGCとFull GCの数、頻度、期間などを分析し、GCの状況をリスト、レポート、グラフなどの形で反映することができます。
  • インターフェースは少し粗いですが、機能は良いです。

HPjmeter

  • このツールは非常に強力ですが、パラメーター -verbose:gc -Xloggc:gc.log によって生成された GC ログしか開くことができません。他のパラメータを追加して生成された gc.log を開くことができません
  • HPjmeter は、以前の HPjtune 機能を統合して、HP マシンで生成されたガベージ コレクション ログ ファイルを分析します

おすすめ

転載: blog.csdn.net/weixin_43811294/article/details/127348157