JVM仕様は自動ストレージ管理を要求しますが、コレクタやヒープレイアウトを 規定していません。したがって、コレクタの動作は、実行されるJVM、リリース、 フラグ、ヒープサイズ、ワークロードの特性です。
到達可能性とメモリプール #
トレーシングはGCルートから開始されます。GCルートには、実行中スレッドの
スタックとレジスタ、staticフィールド、JNIハンドル、VMランタイム構造体などが
含まれます。ルートから強く到達可能なオブジェクトは生存し続けます。
ソフト参照はメモリ逼迫時にクリアされる可能性があり、弱参照は参照先を保持せず、
ファントム参照はReferenceQueueを通じた事後処理の調整を支援します。これらは
いずれも決定的なリソース解放の代替ではありません。try-with-resourcesを使用し、
Cleanerは安全網としてのみ使用してください。ファイナライゼーションは削除予定
として非推奨です。
Javaヒープにはオブジェクトと配列が格納されます。HotSpotでは、メタスペース、
コードキャッシュ、スレッドスタック、ダイレクトバッファ、GCの管理情報、
ネイティブライブラリがヒープ外のメモリを消費します。-Xmxが上限を設定するのは
Javaヒープだけなので、コンテナの制限ではネイティブメモリ用の余裕を確保する必要が
あります。プール名とメモリ使用量の集計方法は、コレクタおよび実装に依存します。
世代別管理と割り当て #
世代別コレクタは、多くの割り当てが短時間で不要になるという事実を利用します。 新しいオブジェクトは若い領域に割り当てられ、生存したオブジェクトはサバイバー 領域を移動し、古い領域へ昇格することがあります。若い世代の各コレクションで すべての古いオブジェクトを走査することを避けるため、ライトバリアは古い世代から 若い世代へのポインタをカードテーブルまたはリメンバードセットに記録します。 割り当て率、生存集合のサイズ、昇格率、利用可能な退避領域は、ヒープ使用率だけよりも メモリ逼迫を適切に予測します。
HotSpotコレクタのトレードオフ #
HotSpotは異なる目的を持つコレクタを提供します。
- Serialは、小さなヒープで実装オーバーヘッドを最小化します。
- Parallelは、並列のstop-the-world処理によりスループットを優先します。
- G1はヒープをリージョンに分割し、並行処理と退避処理のバランスを取りながら、 ポーズ時間の目標に向けて動作します。
- ZGCは、バリアと並行処理によるリソース使用を伴う代わりに、マーキングと 再配置の大部分を並行して実行し、短いポーズを目指します。
- 選択したディストリビューションが提供する場合、Shenandoahも並行退避を実行し、 ポーズ時間を短縮します。
コレクタの可用性とデフォルトは、JDKベンダーおよびリリースによって変わります。
過去のデフォルトを運用ガイダンスに埋め込むのではなく、
java -XX:+PrintCommandLineFlags -versionと、使用しているリリースのドキュメントで
実行中のランタイムを確認してください。
すべてのトレーシングコレクタには、調整のためのポイントが必要です。ルート処理、 リマーク、一部の退避処理では、アプリケーションスレッドを停止することがあります (STW)。並行フェーズはポーズ時間を短縮しますが、CPUとメモリ帯域幅を消費し、 バリアを必要とし、再配置用の空き領域を必要とします。したがって、ポーズ目標を 短くすると、スループットが低下したり、割り当て圧力下で失敗したりする可能性があります。
証拠に基づくチューニング #
統合ログを有効にし、アプリケーションのレイテンシおよびリソースメトリクスと 相関させます。
java -Xlog:gc*,safepoint:file=gc.log:time,uptime,level,tags ...
java -XX:StartFlightRecording=filename=recording.jfr ...JFRの割り当てイベント、jcmd、保持が疑われる場合のヒープダンプ、CPUおよび
コンテナのメトリクスを使用して、過剰な割り当て、増加する生存集合、断片化、
ネイティブメモリの枯渇を区別します。次の順序でチューニングします。
- 意図しない保持と割り当てホットスポットを排除する。
- 測定した生存集合と割り当てバーストに合わせてヒープサイズを設定する。
- 測定したレイテンシおよびスループットの目標に適したコレクタを選択する。
- 文書化された目標を少数だけ変更する。その後、
- 代表的な負荷測定を繰り返す。
System.gc()は要求であり、正しさを保証する仕組みではありません。また、性能に
大きな影響を与える処理を引き起こす可能性があります。アプリケーションの動作は
コレクションのタイミングに依存してはなりません。
コメント
GitHub で閲覧・コメントする(投稿にはログインが必要です)