JVM パフォーマンス チューニングの目標と方法
JVM パフォーマンス チューニングの目標は、Java アプリケーションの実行時に JVM がコンピュータ リソースをより効率的に使用できるようにして、アプリケーションのパフォーマンスと応答性を向上させることです。具体的には、JVM パフォーマンス チューニングの目標には次の側面が含まれます。
- アプリケーションのスループットの向上: JVM のメモリ管理、ガベージ コレクション、スレッド管理を最適化することで、JVM のオーバーヘッドを削減し、アプリケーションのスループットを向上させます。
- アプリケーション遅延の削減: JVM ガベージ コレクション戦略を最適化し、スレッド プールのサイズを調整することにより、アプリケーション遅延が削減され、ユーザー エクスペリエンスが向上します。
- JVM のメモリ使用量を削減する: JVM のメモリ管理戦略を最適化することで、JVM のメモリ使用量を削減し、システムの安定性を向上させます。
JVM パフォーマンス チューニングの方法には、次の側面が含まれます。
- JVM のメモリ パラメータを調整する: JVM のメモリ パラメータ (-Xms、-Xmx、-Xmn など) を調整することで、JVM のヒープ メモリと非ヒープ メモリのサイズを制御し、メモリ リークや OOM (メモリ不足) などの問題。
- 適切なガベージ コレクターを選択する: JVM にはさまざまなガベージ コレクター (シリアル、パラレル、CMS、G1 など) が用意されており、アプリケーションの特性に応じて適切なガベージ コレクターを選択し、最適なガベージを実現するようにパラメーターを調整します。コレクターのリサイクル効果。
- スレッド プールのサイズを調整する: スレッド プールのサイズを調整することで、スレッドが多すぎたり少なすぎたりすることがなくなり、アプリケーションの同時処理能力が向上します。
- パフォーマンス分析ツールを使用する: パフォーマンス分析ツール (JProfiler、VisualVM、Arthas ツール、jstst jstack jmap コマンドなど) を使用してアプリケーションを分析し、ボトルネックとパフォーマンスの問題を見つけて最適化します。
- コードの最適化: コードを最適化し (頻繁なオブジェクト作成の回避、過剰なメソッド呼び出しの回避など)、JVM オーバーヘッドを削減し、アプリケーションのパフォーマンスを向上させます。
JVMパフォーマンスチューニングのためのメトリクスとツール
JVM パフォーマンス チューニングの指標は、JVM パフォーマンスを測定するための重要な基準です。一般的な指標には次の側面が含まれます。
- ヒープ メモリ使用量: JVM ヒープ メモリの使用量を示します。OOM などのメモリの問題を避けるために、通常は 70% 未満に制御する必要があります。
- ガベージ コレクション時間: JVM がガベージ コレクションに費やした時間を示します。ガベージ コレクション時間が長すぎると、アプリケーションのパフォーマンスに影響します。
- スレッド数: JVM で現在実行されているスレッドの数を示します。スレッドが多すぎたり少なすぎたりすると、アプリケーションのパフォーマンスに影響します。
- CPU 使用率: JVM の CPU 使用率を示します。過剰な CPU 使用率は、アプリケーションのパフォーマンスに影響します。
- 応答時間: アプリケーションがリクエストに応答する時間を示します。ユーザー エクスペリエンスを向上させるには、応答時間を可能な限り短縮する必要があります。
一般的に使用される JVM パフォーマンス チューニング ツールには、次の側面が含まれます。
- JVisualVM: JDKに付属するパフォーマンス解析ツールで、JVMのヒープメモリ、ガベージコレクション、スレッドなどを監視し、スレッド解析やメモリ解析などを行うことができます。
- JProfiler: より詳細なパフォーマンス分析と最適化を提供できる商用パフォーマンス分析ツールであり、複数の JVM 環境とアプリケーション タイプをサポートします。
- GCViewer: JVM の GC ログを分析して、ユーザーがガベージ コレクションの状況を理解するのに役立つオープン ソースのガベージ コレクション ログ分析ツールです。
- VisualGC: JVM メモリ、ガベージ コレクションなどをリアルタイムで監視するために使用できる、視覚的な JVM パフォーマンス監視ツールです。
- Perf: Linux システムに付属するパフォーマンス分析ツールで、システムの CPU、メモリ、I/O などの監視に使用できるほか、JVM のパフォーマンスの監視にも使用できます。
- MAT: MAT は Java メモリ アナライザーであり、正式名は Eclipse Memory Analyzer Tool です。MAT は、開発者が Java アプリケーションのメモリ使用量を迅速に分析し、メモリ リークやメモリの無駄などの問題を発見し、最適化の提案を提供するのに役立ちます。
JVM パフォーマンス チューニングのヒントとアドバイス
ここでは、JVM パフォーマンス チューニングに関するいくつかのヒントとアドバイスを示します。
- 適切なガベージ コレクターを選択する: アプリケーションの特性に従って適切なガベージ コレクターを選択し、実際の状況に応じてパラメーターを調整します。さまざまなアプリケーション シナリオに適したガベージ コレクターが異なります。
- ヒープ メモリ サイズを制御する: JVM ヒープ メモリ サイズを調整することで、メモリ リークや OOM などの問題を回避します。一般に、-Xmx パラメータを物理メモリの約 70% に設定することをお勧めします。
- オブジェクトの作成が多すぎることを避ける: ループ内でオブジェクトを頻繁に作成することを避けてください。また、オブジェクト プールなどの手法を使用してコードを最適化できます。
- スレッド プールを使用する: スレッド プールを使用すると、スレッドが多すぎる、または少なすぎるという状況を回避し、アプリケーションの同時処理能力を向上させることができます。
- 過剰なメソッド呼び出しを避ける: 過剰なメソッド呼び出しは、JVM のオーバーヘッドを増加させ、アプリケーションのパフォーマンスに影響を与えます。コードはインライン化などの手法を通じて最適化できます。
- 過剰な同期を避ける: 過剰な同期は、アプリケーションの同時処理能力を低下させ、アプリケーションのパフォーマンスに影響を与えます。コードは、ロック分離などの手法を使用して最適化できます。
- パフォーマンス分析ツールを使用する: パフォーマンス分析ツールを使用すると、パフォーマンスのボトルネックや問題を特定し、最適化することができます。一般的に使用されるパフォーマンス分析ツールには、JProfiler、VisualVM、GCViewer などが含まれます。
- 定期的なパフォーマンス テスト: パフォーマンスの問題を発見し、適時に最適化するための定期的なパフォーマンス テスト。パフォーマンス テストは、JMeter などのツールを使用して実行できます。
- JVM 起動パラメータの最適化: JVM 起動パラメータを調整することで、JVM のパフォーマンスと安定性を向上させることができます。一般的に使用される JVM 起動パラメータには、-Xms、-Xmx、-XX:+UseG1GC などが含まれます。
つまり、JVM パフォーマンス チューニングは、特定のアプリケーションに応じて最適化する必要がある複雑なプロセスです。ガベージ コレクターの適切な選択、ヒープ メモリ サイズの制御、コードの最適化、その他の技術的手段を通じて、JVM のパフォーマンスと安定性を向上させ、アプリケーションのパフォーマンスと応答性を向上させることができます。
実際のJVMパフォーマンスチューニング
JVM関連パラメータ
JVM パラメータは 3 つのカテゴリに分類されます。
- 標準パラメータ (-)。すべての JVM はこれらのパラメータの機能をサポートする必要があり、下位互換性があります。
- 非標準パラメータ (-X)。デフォルトの JVM はこれらのパラメータの機能を実装しますが、すべての JVM 実装が満たされることは保証されず、下位互換性も保証されません。
- 不安定なパラメータ (-XX)。このようなパラメータは JVM 実装ごとに異なり、将来サポートされなくなる可能性があるため、使用には注意してください
JVM標準パラメータ
- -server/-client: JVM 動作モードを指定します。-server はサーバー モードを意味し、長時間実行されるサーバー アプリケーションを最適化します。-client はクライアント モードを意味し、起動速度と応答時間を最適化します。
- -classpath/-cp: クラス ファイルとリソース ファイルを検索するためのクラスパスを指定します。
- -Dproperty=value: システム プロパティを設定します。これは、アプリケーションの System.getProperty() メソッドを通じて取得できます。
- -verbose:class: クラス名、ロード時間、クラスローダーなどのクラスロード情報を表示します。
- -version: JVM のバージョン情報を表示します。
- -showversion: JVM バージョン情報とビルド情報を表示します。
- -help: JVM コマンドラインパラメータのヘルプ情報を表示します。
スタックメモリ設定パラメータ
- -Xms: 初期ヒープ サイズ、デフォルト値はメモリの 1/64
- -Xmx: 最大ヒープ サイズ、デフォルト値はメモリの 1/4
- -Xmn: 若い世代の初期サイズ。-Xmn パラメータのデフォルト値は、若い世代と古い世代の比率が 1:2 です。つまり、若い世代がヒープ全体の 1/3 を占めます。
- -XX:NewSize: 若い世代のサイズを設定します。-Xmn と -XX:NewSize の違い: パラメータの範囲が異なります: -Xmn パラメータは若い世代にのみ作用しますが、-XX:NewSize パラメータは若い世代とサバイバー領域に作用するパラメータのデフォルト値は異なります: -Xmn パラメータのデフォルト値はヒープ サイズに基づいて計算され、-XX:NewSize パラメータのデフォルト値は 0、これは、JVM が若い世代と Survivor 領域のサイズを自動的に計算することを意味します。
- -XX:MaxNewSize: 若い世代の最大値
- -XX:NewRatio: 若い世代 (エデンと 2 つのサバイバー エリアを含む) と古い世代 (永続世代を除く) の比率
- -XX:SurvivorRatio: Eden エリアと Survivor エリアのサイズ比率。デフォルト値は 8 に設定されており、2 つの Survivor エリアと 1 つの Eden エリアの比率は 2:8 となり、1 つの Survivor エリアは 1/10 を占めます。若い世代全体の
- -Xss: 各スレッドのスタック サイズ。JDK5.0 以降の各スレッドのスタック サイズのデフォルト値は 1M です。
- -XX:ThreadStackSize: スレッド スタックのサイズの設定に使用されます。 -Xss と -XX:ThreadStackSize の違い: パラメーターのスコープが異なります。 -XX:ThreadStackSize パラメーターは、すべてのスレッドのスタック サイズの設定に使用され、-Xss パラメーターは単一スレッドのスタック サイズを設定するために使用されます。
- -XX:LargePageSizeInBytes: 大きなページのサイズを設定するために使用されます。ヒュージ ページを有効にすると、メモリ アクセスの効率が向上し、アプリケーションのパフォーマンスと応答性が向上します。ただし、ラージ ページを有効にするとメモリの断片化の問題が発生する可能性があり、メモリの使用効率と安定性に影響を与えることに注意してください。
- -XX:MaxTenuringThreshold: 若い世代と古い世代の間でオブジェクトが存続する最大存続期間を設定するために使用されます。若い世代は、新しく作成されたオブジェクトを格納するために使用される Java ヒープ メモリの一部です。若い世代がいっぱいになると、ガベージ コレクションがトリガーされ、残っているオブジェクトが古い世代に移動されます。デフォルト値は 15 です。これは、オブジェクトが最大 15 回のガベージ コレクションに耐えた後に古い世代に移動されることを意味します。
- -Xnoclassgc: JVM がガベージ コレクション中に不要なクラスをリサイクルするかどうかを制御するために使用されます。
- -XX:SoftRefLRUPolicyMSPerMB: ソフト参照オブジェクトの LRU ポリシーを設定するための時間制限。デフォルト値は 1000 です。これは、ソフト参照オブジェクトがメモリ空間 1 MB あたり 1 秒間存続できることを意味します。-XX:SoftRefLRUPolicyMSPerMB パラメータを設定することで、ソフト参照オブジェクトの LRU ポリシーを調整できます。これにより、ソフト参照オブジェクトのリサイクル ポリシーとメモリ使用量に影響を与えます。
- -XX:PretenureSizeThreshold: 新世代のメモリ領域内のオブジェクトが旧世代のメモリ領域に直接入るためのしきい値サイズを設定するために使用されます。デフォルト値は 0 で、古い年齢への直接アクセスが無効であることを意味します。
- -XX:TLABWasteTargetPercent: スレッド ローカル割り当てバッファ (スレッド ローカル割り当てバッファ、TLAB) の無駄のしきい値パーセンテージを設定するために使用されます。デフォルト値は 1 です。これは、スレッドローカル割り当てバッファー内の無駄なスペースが合計スペースの 1% を超えることができないことを意味します。
- -XX:+CollectGen0First: フル GC の実行時に JVM が最初に新しい世代のメモリ領域を再利用するかどうかを制御するために使用されます。
メタデータ設定パラメータ
- -XX:MetaspaceSize: メタデータ領域の初期サイズを設定します。
- -XX:MaxMetaspaceSize: メタデータ領域の最大サイズを設定します。
- -XX:MinMetaspaceFreeRatio: メタデータ領域の最小空き領域率を設定します。
- -XX:MaxMetaspaceFreeRatio: メタデータ領域の最大空き領域率を設定します。
JITセットアップパラメータ
ガベージコレクタ設定パラメータ
パラメータ名 | 意味 | デフォルト | |
---|---|---|---|
-XX:+UseParallelGCFull | GC は並列 MSC を使用します | パラレル コレクタとしてガベージ コレクタを選択します。この構成は若い世代にのみ有効です。つまり、上記の構成では、若い世代は同時コレクションを使用しますが、古い世代は引き続きシリアル コレクションを使用します。 | |
-XX:+UseParNewGC | 若い世代に並行して収集を設定する | CMS 収集と同時に JDK5.0 以降を使用できます。JVM はシステム構成に従って自動的に設定されるため、この値を設定する必要はありません | |
-XX:ParallelGCThreads | 並列コレクターのスレッド数は、プロセッサーの数と同じになるように構成するのが最適です。これは CMS にも当てはまります。 | ||
-XX:+UseParallelOldGC | 旧世代のガベージコレクション方式は並列コレクション(Parallel Compacting)です。 | これはJAVA 6で登場したパラメータオプションです。 | |
-XX:MaxGCPauseMillis | 若い世代ごとのガベージ コレクションの最大時間 (最大一時停止時間) | この時間を満たせない場合、JVM はこの値を満たすように若い世代のサイズを自動的に調整します。 | |
-XX:+UseAdaptiveSizePolicy | 若い世代の領域のサイズと、それに対応する生存者領域の割合を自動的に選択します | このオプションを設定すると、パラレル コレクターは、ターゲット システムによって指定された最小対応時間または収集頻度を達成するために、若い世代領域のサイズと対応する Survivor 領域の割合を自動的に選択します。この値は、次の場合にオンにすることをお勧めします。パラレルコレクターが使用されます。 | |
-XX:GCTimeRatio | プログラムの実行時間に対するガベージ コレクション時間の割合を設定します。式は次のとおりです。 | 1/(1+n) | |
-XX:+ScavengeBeforeFullGCFull | GC の前に YGCtrue を呼び出す | フル GC の前に若い世代の GC を実行します。 |
CMS関連パラメータ
- -XX:+UseConcMarkSoupGC: CMS メモリ コレクションを使用する
- -XX:+AggressiveHeap : パフォーマンスベースのヒープ メモリ構成を有効にするために使用されます。このパラメータを有効にすると、JVM は現在のシステム ハードウェア構成とメモリ使用量に応じてヒープ メモリ サイズとガベージ コレクション戦略を自動的に調整し、最高のパフォーマンスとメモリ使用率を実現します。
- -XX:CMSFullGCsBeforeCompaction : メモリ圧縮を実行する回数
- -XX:+CMSParallelRemarkEnabled: マークの一時停止を減らします
- -XX+UseCMSCompactAtFullCollection: FULL GC 中の古い世代の圧縮
- -XX:+UseCMSInitiatingOccupancyOnly: 手動定義の初期化定義を使用して CMS 収集を開始します
- -XX:CMSInitiatingOccupancyFraction=70: cms をガベージ コレクションとして使用し、使用率が 70% になった後に CMS コレクションを開始します。
GCログ設定パラメータ
- -XX:+PrintGC: 出力形式: [GC 118250K->113543K(130112K)、0.0094143 秒] [
フル GC 121376K->10414K(130112K)、0.0650971 秒] - -XX:+PrintGCDetails: 出力形式: [GC [DefNew: 8614K->781K(9088K), 0.0123035 秒] 118250K->113543K(130112K), 0.0124633 秒] [GC [DefNew: 8614K->8614K(90 88K),
0.0000665 秒][保持期間: 112761K->10414K(121024K)、0.0433488 秒] 121376K->10414K(130112K)、0.0436268 秒] - -XX:+PrintGCTimeStamps
- -XX:+PrintGC:PrintGCTimeStamps: -XX:+PrintGC -XX:+PrintGCDetails と混合可能 出力
形式: 11.851: [GC 98328K->93620K(130112K), 0.0082960 秒] - -XX:+PrintGCApplicationStoppedTime: ガベージ コレクション中にプログラムが中断された時間を出力します。上記と混合できます。
- -XX:+PrintGCApplicationConcurrentTime: 各ガベージ コレクションの前にプログラムの中断のない実行時間を出力します。上記と組み合わせることができます。
- -XX:+PrintHeapAtGC : GC 前後の詳細なスタック情報を出力します。
- -Xloggc:filename: 関連するログ情報を分析用にファイルに記録します。上記とともに使用します。
- -XX:+PrintClassHistogram
- -XX:+PrintTLAB
- -XX:+PrintTenuringDistribution: 各マイナー GC 後の新しい生存サイクルのしきい値を表示します。
他の
- -XX:+UseFastAccessorMethods: 高速アクセサー メソッドを有効にするために使用されます。高速アクセサー メソッドは、ゲッター メソッドとセッター メソッドを介してオブジェクトのプロパティにアクセスする代わりに、オブジェクトのフィールドに直接アクセスすることで、オブジェクトのプロパティへのアクセス効率を向上させることができる最適化手法です。引数を true にすると、クイック アクセサー メソッドが有効になります。クイック アクセサー メソッドを有効にすると、オブジェクトの内部実装の詳細が公開され、コードがオブジェクトの特定の実装に依存するようになるため、プログラムの保守性とスケーラビリティに影響を与える可能性があることに注意してください。したがって、特定のアプリケーションのシナリオと要件に従って選択および調整する必要があります。
- -XX:+DisableExplicitGC: System.gc() をオフにする
- -XX:+UseBiasedLocking: ロック機構のパフォーマンス向上
- -XX:MaxDirectMemorySize: ダイレクト メモリの最大サイズを設定します。
実際の構成
更新予定