JVM シリーズ - JVM 最適化#
JDK8 に依存し、内容は以下から整理されています:
GC ログフォーマット#
画像は Jvm シリーズ (八) 知識点総覧 から引用
Young GC ログ:
Full GC ログ:
JVM 最適化コマンド#
jps#
コマンドフォーマット:
jps [options] [hostid]
option パラメータ
-l
: 主クラスの完全名または jar パスを出力-q
: LVMID のみを出力-m
: JVM 起動時に main () に渡されたパラメータを出力-v
: JVM 起動時に指定された JVM パラメータを出力
[option]、[hostid] パラメータは省略可能
例
$ jps -l -m
28920 org.apache.catalina.startup.Bootstrap start
11589 org.apache.catalina.startup.Bootstrap start
25816 sun.tools.jps.Jps -l -m
jstat#
コマンドフォーマット
jstat [option] LVMID [interval] [count]
パラメータ
- [option] : 操作パラメータ
- LVMID : ローカル仮想マシンプロセス ID
- [interval] : 連続出力の時間間隔
- [count] : 連続出力の回数
option パラメータの詳細#
-class#
クラスのロード、アンロード数、総スペースおよび消費時間を監視
$ jstat -class 11589
Loaded Bytes Unloaded Bytes Time
7035 14506.3 0 0.0 3.67
- Loaded : ロードされたクラスの数
- Bytes : クラスのバイトサイズ
- Unloaded : アンロードされたクラスの数
- Bytes : アンロードされたクラスのバイトサイズ
- Time : ロード時間
-compiler#
JIT コンパイルされたメソッドの数と時間を出力
$ jstat -compiler 1262
Compiled Failed Invalid Time FailedType FailedMethod
2573 1 0 47.60 1 org/apache/catalina/loader/WebappClassLoader findResourceInternal
- Compiled : コンパイルされた数
- Failed : コンパイル失敗数
- Invalid : 無効数
- Time : コンパイルにかかった時間
- FailedType : 失敗タイプ
- FailedMethod : 失敗したメソッドの完全修飾名
-gc#
ガベージコレクションヒープの動作統計、一般的なコマンド
$ jstat -gc 1262
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
22016.0 21504.0 15436.2 0.0 305664.0 90988.0 699392.0 15828.7 31024.0 30336.3 3632.0 3507.6 12 0.438 1 0.045 0.483
-
C は Capacity の略、U は Used の略
-
S0C : survivor0 区の総容量
-
S1C : survivor1 区の総容量
-
S0U : survivor0 区の使用済み容量
-
S1U : survivor1 区の使用済み容量
-
EC : Eden 区の総容量
-
EU : Eden 区の使用済み容量
-
OC : Old 区の総容量
-
OU : Old 区の使用済み容量
-
MC : Metacspace メタスペース容量
-
MU : Metacspace メタスペース使用容量
-
CCSC : 圧縮クラススペース容量
-
CCSU : 圧縮クラススペース使用容量
-
YGC : 新生代ガベージコレクション回数
-
YGCT : 新生代ガベージコレクション時間
-
FGC : 老年代ガベージコレクション回数
-
FGCT : 老年代ガベージコレクション時間
-
GCT : ガベージコレクションの総消費時間
-gccapacity#
-gc と同様ですが、Java ヒープの各領域で使用される最大、最小スペースも出力します
$ jstat -gccapacity 1262
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
349184.0 349184.0 349184.0 22016.0 21504.0 305664.0 699392.0 699392.0 699392.0 699392.0 0.0 1077248.0 31024.0 0.0 1048576.0 3632.0 12 1
- NGCMN : 新生代が占有する最小スペース
- NGCMX : 新生代が占有する最大スペース
- NGC : 現在の新生代容量
- EC : 現在の新生代 Eden 区容量
- OGCMN : 老年代が占有する最小スペース
- OGCMX : 老年代が占有する最大スペース
- OGC:現在の老年代の容量 (KB)
- OC:現在の老年代のスペース (KB)
- MCMN : metaspace メタスペースが占有する最小スペース
- MCMX : metaspace メタスペースが占有する最大スペース
- MC : 現在の metaspace メタスペースの容量
- CCSMN : 圧縮クラススペースが占有する最小スペース
- CCSMX : 圧縮クラススペースが占有する最大スペース
- CCSC : 圧縮クラススペースの容量
-gcutil#
-gc と同様ですが、使用済みスペースが総スペースに占める割合を出力します
$ jstat -gcutil 28920
S0 S1 E O P YGC YGCT FGC FGCT GCT
12.45 0.00 33.85 0.00 4.44 4 0.242 0 0.000 0.242
-gccause#
ガベージコレクション統計の概要(-gcutil と同様)、最近の 2 回のガベージコレクションイベントの原因を追加
$ jstat -gccause 28920
S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC
12.45 0.00 33.85 0.00 4.44 4 0.242 0 0.000 0.242 Allocation Failure No GC
- LGCC:最近のガベージコレクションの原因
- GCC:現在のガベージコレクションの原因
-gcnew#
新生代の動作を統計
$ jstat -gcnew 28920
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
419392.0 419392.0 52231.8 0.0 6 6 209696.0 3355520.0 1172246.0 4 0.242
- TT:Tenuring threshold(昇進閾値、老年代に昇進するために必要な年齢)
- MTT:最大 tenuring threshold
- DSS:survivor 領域のサイズ (KB)
-gcnewcapacity#
新生代とその対応するメモリスペースの統計
$ jstat -gcnewcapacity 28920
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
4194304.0 4194304.0 4194304.0 419392.0 419392.0 419392.0 419392.0 3355520.0 3355520.0 4 0
- NGC: 現在の若い世代の容量 (KB)
- S0CMX: 最大の S0 スペース (KB)
- S0C: 現在の S0 スペース (KB)
- ECMX: 最大 eden スペース (KB)
- EC: 現在 eden スペース (KB)
-gcold#
旧生代の動作を統計
$ jstat -gcold 28920
PC PU OC OU YGC FGC FGCT GCT
1048576.0 46561.7 6291456.0 0.0 4 0 0.000 0.242
-gcoldcapacity#
旧生代のサイズとスペースを統計
$ jstat -gcoldcapacity 28920
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
6291456.0 6291456.0 6291456.0 6291456.0 4 0 0.000 0.242
-gcmetacapacity#
metaspace メタスペースの動作統計
$ jstat -gcmetacapacity 3491
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 1077248.0 31024.0 0.0 1048576.0 3632.0 12 1 0.045 0.483
-printcompilation#
hotspot コンパイルメソッドの統計
$ jstat -printcompilation 28920
Compiled Size Type Method
1291 78 1 java/util/ArrayList indexOf
- Compiled:実行されたコンパイルタスクの数
- Size:メソッドのバイトコードのバイト数
- Type:コンパイルタイプ
- Method:コンパイルメソッドのクラス名とメソッド名。クラス名は「/」で「.」の代わりに区切られます。メソッド名はクラスのメソッド名です。フォーマットは HotSpot - XX:+PrintComplation オプションに一致します。
jmap#
jmap (JVM Memory Map) コマンドはヒープダンプファイルを生成するために使用されます。このコマンドを使用しない場合は、-XX:+HeapDumpOnOutOfMemoryError パラメータを使用して、仮想マシンが OOM の際に自動的にダンプファイルを生成することができます。jmap はダンプファイルを生成するだけでなく、finalize 実行キュー、Java ヒープおよび永続世代の詳細情報(現在の使用率、現在使用している収集器など)を照会することもできます。
コマンドフォーマット
jmap [option] LVMID
option パラメータ
-dump
: ヒープダンプスナップショットを生成-finalizerinfo
: F-Queue キューで Finalizer スレッドによる finalizer メソッドの実行を待っているオブジェクトを表示-heap
: Java ヒープの詳細情報を表示-histo
: ヒープ内のオブジェクトの統計情報を表示-permstat
: 永続世代の統計を表示-F
: -dump が応答しない場合、強制的にダンプスナップショットを生成
jhat#
jhat (JVM Heap Analysis Tool) コマンドは jmap と組み合わせて使用され、jmap が生成したダンプを分析するために使用されます。jhat はミニ HTTP/HTML サーバーを内蔵しており、ダンプの分析結果を生成した後、ブラウザで確認できます。ここで注意が必要なのは、一般的にサーバー上で直接分析を行うことはなく、jhat は時間がかかり、ハードウェアリソースを消費するプロセスであるため、サーバーで生成されたダンプファイルをローカルまたは他のマシンにコピーして分析することが一般的です。
コマンドフォーマット
jhat [dumpfile]
パラメータ
-stack false|true
オブジェクト割り当て呼び出しスタックのトレースを無効にします。割り当て位置情報がヒープダンプに利用できない場合、このフラグを false に設定する必要があります。デフォルト値は true です。-refs false|true
オブジェクト参照のトレースを無効にします。デフォルト値は true です。デフォルトでは、返されるポインタは他の特定のオブジェクトへのオブジェクトを指し、逆リンクや入力参照など、ヒープ内のすべてのオブジェクトを統計 / 計算します。-port port-number
jhat HTTP サーバーのポート番号を設定します。デフォルト値は 7000 です。-exclude exclude-file
オブジェクトクエリ時に除外する必要があるデータメンバーリストファイルを指定します(到達可能なオブジェクトクエリから除外すべきデータメンバーをリストしたファイル)。例えば、ファイルが java.lang.String.value をリストしている場合、特定のオブジェクト Object o から到達可能なオブジェクトリストを計算する際に、java.lang.String.value に関連する参照パスはすべて除外されます。-baseline exclude-file
基準ヒープダンプを指定します。2 つのヒープダンプに同じオブジェクト ID を持つオブジェクトは新しいものではないとマークされます。他のオブジェクトは新しいとマークされます。2 つの異なるヒープダンプを比較する際に便利です。-debug int
デバッグレベルを設定します。0 はデバッグ情報を出力しないことを意味します。値が大きいほど、より詳細なデバッグ情報が出力されます。-version
起動後にバージョン情報のみを表示して終了します。-J< flag >
jhat コマンドは実際に JVM を起動して実行されるため、-J を使用して JVM を起動する際にいくつかの起動パラメータを渡すことができます。例えば、-J-Xmx512m は jhat を実行する Java 仮想マシンが使用する最大ヒープメモリを 512MB に設定します。複数の JVM 起動パラメータを使用する必要がある場合は、複数の - Jxxxxxx を渡します。
jstack#
jstack は Java 仮想マシンの現在のスレッドスナップショットを生成するために使用されます。スレッドスナップショットは、現在の Java 仮想マシン内の各スレッドが実行しているメソッドスタックの集合であり、スレッドが長時間停止している原因を特定することを目的としています。例えば、スレッド間のデッドロック、無限ループ、外部リソースの要求による長時間待機などです。
コマンドフォーマット
jstack [option] LVMID
option パラメータ
-F
: 通常の出力要求が応答しない場合、強制的にスレッドスタックを出力-l
: スタックの他に、ロックに関する追加情報を表示-m
: ローカルメソッドが呼び出された場合、C/C++ のスタックを表示
jinfo#
jinfo (JVM Configuration info) コマンドは、仮想マシンの実行パラメータをリアルタイムで確認および調整するためのものです。以前の jps -v コマンドでは指定されたパラメータのみを表示できましたが、表示されていないパラメータの値を確認するには jinfo コマンドを使用する必要があります。
コマンドフォーマット
jinfo [option] [args] LVMID
option パラメータ
-flag
: 指定した args パラメータの値を出力-flags
: args パラメータを必要とせず、すべての JVM パラメータの値を出力-sysprops
: システムプロパティを出力、System.getProperties () と同等
JVM 最適化設定パラメータ#
ヒープ設定#
-Xms
: ヒープの最小スペースサイズを設定-Xmx
: ヒープの最大スペースサイズを設定-XX:NewSize=n
: 若い世代のサイズを設定-XX:NewRatio=n
: 若い世代と老年代の比率を設定します。例えば、3 の場合、若い世代と老年代の比率は 1:3 で、若い世代は全体の若い世代と老年代の 1/4 を占めます。-XX:SurvivorRatio=n
: 若い世代の Eden 区と 2 つの Survivor 区の比率。注意:Survivor 区は 2 つあります。3 の場合、Eden:3 Survivor:2 で、1 つの Survivor 区は全体の若い世代の 1/5 を占めます。-XX:MaxPermSize=n
: 永続世代のサイズを設定
収集器設定#
-XX:+UseSerialGC
: シリアル収集器を設定-XX:+UseParallelGC
: 並列収集器を設定-XX:+UseParalledlOldGC
: 並列老年代収集器を設定-XX:+UseConcMarkSweepGC
: 同時収集器を設定
並列収集器設定#
-XX:ParallelGCThreads=n
: 並列収集器が収集時に使用する CPU 数を設定。並列収集スレッド数-XX:MaxGCPauseMillis=n
: 並列収集の最大停止時間を設定(この時間に達してもガベージコレクタが回収を完了しない場合、回収を停止します)-XX:GCTimeRatio=n
: ガベージコレクション時間がプログラムの実行時間に占める割合を設定します。公式は:1/(1+n)-XX:+CMSIncrementalMode
: 増分モードに設定します。単一 CPU の状況に適しています。-XX:ParallelGCThreads=n
: 同時収集器の若い世代の収集方法を並列収集に設定する際に使用する CPU 数。並列収集スレッド数
ガベージコレクション統計情報設定#
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
JVM 最適化のケーススタディ#
参考リンク: