JDK 19 G1/Parallel/Serial GC changes

原文はこちら。
The original article was written by Thomas Schatzl (OpenJDK developer, Oracle).
https://tschatzl.github.io/2022/09/16/jdk19-g1-parallel-gc-changes.html

JDK 19のGAがもうそこまで来ています(訳注:GA前の文章です)。

JDK 19
https://openjdk.java.net/projects/jdk/19/

本リリースにおけるHotSpotのStop-the-world GC(G1とParallel GC)の変更点と特に改善点はまた別の機会にまとめます。

今回のリリースでは、全体的にGC領域に特化したJEPはありませんでした。GC領域の支援を必要とする大きな変更が2つありました。

仮想スレッドは、スレッドスタックを含むJavaヒープ上のオブジェクトを導入します。これらの新しい種類のオブジェクトは、すべてのGCアルゴリズムで適切に扱われる必要があります。しかし、これらのオブジェクトの主たる複雑さは、これらのオブジェクトが参照する、古いコンパイル済みコードのアンロードにあたり、少なくともJDK 19では、GCとコードキャッシュスイーパー(「コンパイル済みコードのためのGC」)の間のいくつかのかなり複雑な動きが必要な点です。例えば、GCにメソッドアンロードの完全に管理(JDK-8290025)させたり、積極的過ぎるスィープに対する完全な管理(JDK-8284404)させたりするような、改善のための作業がすでに始まっています。

[JDK-8290025] Remove the Sweeper
https://bugs.openjdk.org/browse/JDK-8290025
[JDK-8284404] Too aggressive sweeping with Loom
https://bugs.openjdk.org/browse/JDK-8284404

プレビューオプションでLoomを有効にしない場合、これらの問題は発生しません。

JDK 8はメンテナンスリリースになりました。以下のURLに示す変更により、以前クラッシュを発生する可能性がある java.lang.ref.Reference における未定義の挙動を削除されました。この変更の副作用として、GCでの参照処理が少し改善される可能性があります。

JSR 337 Maintenance Release 4: Java SE 8
https://jcp.org/aboutJava/communityprocess/maintenance/jsr337/jsr337-mr4-changes.html

その他、JDK 19のHotspot GCサブコンポーネント全体の変更点一覧はこちらをご覧ください。合計で約200の変更点が解決またはクローズされたことがわかります。上記の2つのプロジェクトによるものです。

ZGCにざっと目を通すと、このリリースでの変更は軽微であることがわかります。JDK-8255495 は、いくつかのバグ修正に加えて、部分的な CDS サポート (クラスデータはアーカイブされるが、ヒープオブジェクトはアーカイブされない) を追加しました。

OpenJDK Wiki – ZGC
https://wiki.openjdk.java.net/display/zgc/Main
[JDK-8255495] Support CDS Archived Heap for uncompressed oops
https://bugs.openjdk.org/browse/JDK-8255495

ここしばらくの間、主たる注力ポイントはgenerational ZGCです。以下のURLから開発状況を追うことができますので、楽しみにしていてください。

openjdk/zgc at zgc_generational
https://github.com/openjdk/zgc/tree/zgc_generational

Parallel GC

Parallel GCではアーカイブ済みヒープオブジェクトもサポートするようになりました。この機能はJDK-8274788とともに追加されました。

[JDK-8274788] Support archived heap objects in ParallelGC
https://bugs.openjdk.org/browse/JDK-8274788

JDK-8280705ではFull GCの最初のフェーズにおける作業配分が改善しており、時として非常に大きなパフォーマンス改善を得られる場合があります。

[JDK-8280705] Parallel: Full gc mark stack draining should prefer to make work available to other threads
https://bugs.openjdk.org/browse/JDK-8280705

Serial GC

Serial GCでは目立った変更はありませんでした。

G1 GC

Parallel GCに対する前述の最適化と同じものをG1 Full GCのために実装したJDK-8280396を除き、目立った改善点はありませんでした。

[JDK-8280396] G1: Full gc mark stack draining should prefer to make work available to other threads
https://bugs.openjdk.org/browse/JDK-8280396

JDK 19では、で導入されたネイティブメモリ利用の回帰

JDK 19では、JDK 19のリリースプロセスの最後の最後でネイティブメモリ使用量のリグレッションが入り込んでしまい、修正を統合することができませんでした。リリースノートで回避策を提供しています。このリグレッションは、JDK 19.0.1以降で対処済みです。

[JDK-8292654] G1 remembered set memory footprint regression after JDK-8286115
https://bugs.openjdk.org/browse/JDK-8292654
[JDK-8293707] Release Note: G1 Remembered set memory footprint regression after JDK-8286115
https://bugs.openjdk.org/browse/JDK-8293707

What’s next

もちろん、私たちはとっくにJDK 20の開発に着手しています。ここでは、現在開発中で、注目されそうな興味深い変更点を簡単に列挙してみます。多くのものは実のところすでに統合済みで、仮想スレッド (Virtual Threads) とJDK 8 MR4に数多くのリソースが取られました。それにより、JDK 19のFCを過ぎて変更がスリップしています。それらを除けば、他のものはJDK 20に導入される保証はありません。完了した時点で統合される予定です。

[1] JDK 20で入るJDK-8210708との統合により、G1におけるネイティブメモリ利用量が大幅に削減されました。これはJavaヒープ全体にまたがるマークビットマップの一つを削除する、というものです。

[JDK-8210708] Use single mark bitmap in G1
https://bugs.openjdk.org/browse/JDK-8210708

“Concurrent Marking in G1″というブログエントリこの変更と変更による影響について詳細に説明しています。

Concurrent Marking in G1
https://tschatzl.github.io/2022/08/04/concurrent-marking.html
https://logico-jp.io/2022/09/17/concurrent-marking-in-g1/

この変更により、JDK 19 で当初予測されていたネイティブ メモリ フットプリントが、下図の”Prototype (calculated)” でついに実現されました。

エントリはこちら。

JDK 18 G1/Parallel/Serial GC changes
https://tschatzl.github.io/2022/03/14/jdk18-g1-parallel-gc-changes.html#memory-usage-jdk19-forecast
https://logico-jp.io/2022/04/05/jdk-18-g1-parallel-serial-gc-changes/#memory-usage-jdk19-forecast

[2] もう一つの重要な変更は、待避失敗時の並列性(およびパフォーマンス)の改善が既にJDK 20に統合されています。これはJEP 423 (Region Pinning in G1) で説明されているように、リージョンピニングの将来のサポートに向けたものです。

[JDK-8256265 G1] Improve parallelism in regions that failed evacuation
https://bugs.openjdk.org/browse/JDK-8256265
JEP 423: Region Pinning for G1
https://openjdk.org/jeps/423

[3] Concurrent refinement controlが現在JDK-8137022の一環で改訂されています。

[JDK-8137022] Concurrent refinement thread adjustment and (de-)activation suboptimal
https://bugs.openjdk.org/browse/JDK-8137022

一般に同時並行でリファインするカードの処理速度がよりスムーズになりました。その副次的な効果として、G1はより多くのダーティカード (dirty card) をより長くキューに残し、新たなダーティカードの生成率を下げ、最終的に同時リファインメント作業量を減らすことができるようになりました。これにより、アプリケーションスループットが向上します。

[4] バーストでオブジェクトを昇格するアプリケーションでは、1-200msではなく、数秒のオーダーの長時間のポーズ時間のスパイクを示す可能性がありました。特に大規模なAarch64マシンはその影響を受けやすかったのですが、これはプロモーションアロケーションバッファ (PLAB) のサイズが訓練されていない (または誤って訓練されている) ことによって引き起こされます

バーストでオブジェクトをプロモートするアプリケーションでは、1-200ms ではなく、低額の秒数の範囲で非常に長い休止時間のスパイクを示す可能性がありました。特に大規模な Aarch64 マシンはその影響を受けやすかったです。これは、プロモーションアロケーションバッファ (PLAB) のサイズが訓練されていない (または誤って訓練されている) ことによって発生します。 JDK-8288966 はこの問題を解決するために、GC中に PLAB のサイズを適度に積極的に変更する機能を追加しています。

[JDK-8288966] Better handle very spiky promotion in G1
https://bugs.openjdk.org/browse/JDK-8288966

[5] G1 の予測を改善し、目標ポーズ時間 (-XX:MaxGCPauseMillis) をよりよく守れるようにするための調査が進行中です。目標は、オーバーシュート(遅延スパイクの減少)とアンダーシュートを減らし、目標ポーズ時間を維持しながら、より少ないGCですむようにすることです。アプリケーションによっては、GCに費やされる総時間を大幅に削減し、アプリケーションに多くの時間を割くことができます。効果を示す部品には、例えばJDK-8231731などがあります。

[JDK-8231731] Improve cardinality estimations of combined remembered sets for G1
https://bugs.openjdk.org/browse/JDK-8231731

[6] いくつかの積年の改善を実装することに再び関心が持たれています。

Container-aware heap sizing for OpenJDK
https://mail.openjdk.org/pipermail/hotspot-dev/2022-September/064190.html

  • Hotspot GCを実行時により構成可能にする(例:G1用:JDK-8236073、JDK-8204088)
  • より一層コンテナフレンドリーにするべく、他のテナントに対する影響を少なくする(例:JDK-8238687)

[JDK-8236073] G1: Use SoftMaxHeapSize to guide GC heuristics
https://bugs.openjdk.org/browse/JDK-8236073
[JDK-8204088] Dynamic Max Memory Limit
https://bugs.openjdk.org/browse/JDK-8204088
[JDK-8238687] Investigate memory uncommit during young collections in G1
https://bugs.openjdk.org/browse/JDK-8238687

まだまだ続きます。

Thanks go to…

素晴らしいJDKリリースに貢献してくれたみなさんに感謝です。次のリリースでお会いしましょう。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中