HN 日本語サマリー

← 一覧へ戻る
プログラミング

JDK 27 G1/Parallel/Serial GCの変更点

JDK 27 G1/Parallel/Serial GC Changes (tschatzl.github.io)

14 pointsby 0x54MUR412 コメント

要約

OpenJDK 28のリリースが近づく中、JDK 27におけるHotSpot VMのストップ・ザ・ワールド(STW)コレクタに関する興味深い変更点について解説しています。G1 GCがデフォルトコレクタとなり、パフォーマンスやメモリ管理の改善が行われました。Parallel GCではバグ修正によるパフォーマンス向上が見られ、Serial GCには特筆すべき変更はありませんが、デフォルトコレクタから外れるケースが出てきました。全体として、メモリ管理の自動化と効率化に向けた取り組みが進んでいます。

全文翻訳

OpenJDK 28のリリースが目前に迫っているため、HotSpot VMにおけるストップ・ザ・ワールドコレクタの興味深い変更点について改めて議論する時期が来たと考えています。JDK 27のGCサブコンポーネントで解決/クローズされた変更点の完全なリストはここにあり、合計で約350件の変更が含まれています。この生の件数は前回のリリースと一致しており、当時と同様に、GCコードにおけるかなりの数のリファクタリングとクリーンアップにより、これらの数値はやや誇張されている可能性があります。 特に注目すべき領域の1つは、クロススレッド共有変数を、volatileおよび適切なAtomicAccessメソッドの使用から、JDK-8367013で導入されたAtomic<T>の使用へと移行することです。これにより、それらの使用がより明確になります。その他の注目すべきリファクタリングには、G1ステートマシンのクリーンアップ(非常に古いものも含む)やその他のコード改善が含まれます。これらが変更の約半分を占めます。さらに約35%の変更は、バグ修正、一般的な正確性および堅牢性の向上に関連しています。残りは、HotSpotのSTWコレクタの新しいまたは実質的に改訂された動作と機能に関するもので、この部分について本稿ではさらに掘り下げていきます。 これらの変更に混じって、JEP 401: Value Objects (Preview) のためのインフラ作業がありました。例えば、オブジェクトイテレータの適応や、値オブジェクトの早期回収などです。 G1 GC このリリースで最も影響力のある変更は、おそらくJEP 523: Make G1 the Default Garbage Collector in All Environmentsでしょう。コマンドラインで明示的にガベージコレクションアルゴリズムを指定しない場合、G1がデフォルトのコレクタになりました。例外はなく、デフォルトではどのケースでもSerial GCは使用されません(ただし、G1がOpenJDKのディストリビューションに含まれていない場合を除く)。私たちはG1がデフォルトコレクタの要件をうまく満たしていると考え、秘匿された環境条件に応じて何かを選択することは、利点よりも負担の方が大きいと考えていました。過去数回のリリースで、スループット、フットプリント、レイテンシのプロファイルはSerial GCに徐々に近づいてきました。そのため、スイッチを切り替える時期が来たと感じました。もし純粋で変更されていないSerial GCで顕著な違いに気づいた場合は、-XX:+UseSerialGCオプションを使用してSerial GCを選択することもできます。アプリケーションのプロファイルによってはSerial GCの方が適しているケースが明らかに存在します。G1はどこでも最適というわけではありませんが、間違いなく開始するには最適だと考えています。 その変更に加えて、他にもいくつかあります。 G1は、もはやFull GC後に(任意の値である)-XX:MinHeapFreeRatioと-XX:MaxHeapFreeRatioのパーセンテージに基づいてヒープをリサイズしません。つまり、それらのデフォルト値は、通常の他のヒューリスティックベースのサイジング(例:アプリケーションのCPU使用率に対するガベージコレクタのCPU使用率)に影響を与えないように設定されています。JDK-8238686は、それらのデフォルト値をそれぞれ40%および70%から0%および100%に設定しました。元のデフォルト値は、このヒューリスティックとCPU使用率ベースのヒューリスティックなどが互いに競合し、不要なJavaヒープサイズの変更を引き起こし、Full GCがヒープを縮小した後、他のヒューリスティックがほぼ即座に変更を元に戻す際にパフォーマンスの問題を引き起こしていました。それ以外では、これらのフラグの機能は維持されています。 同時マーキングの適応開始は、以前は不要な継続的な同時作業を引き起こしていた悪条件に対する耐性が向上しました(JDK-8379846、JDK-8381006)。 回収可能なはずの巨大オブジェクトが、弱参照(例:java.lang.ref.Referenceインスタンス)によって意図せず保持されていた問題が修正されました(JDK-8378331、JDK-8378336)。 軽微な観測可能な変更としては、G1のクリーンアップ一時停止は、JDK-8386332でJavaヒープを変更しないため、MemoryPoolMXBean.getCollectionUsage()を更新しなくなりました。 JDK-8373894では、コピーするのに十分なスペースが見つからなかったガベージコレクションが、ガベージコレクタのCPU使用率に含まれていませんでした。それらを含めることで、ヒープサイジングの決定が改善されます。 Parallel GC Parallel GCには、パフォーマンスを向上させる可能性のある注目すべきバグ修正がいくつかありました。 適応型テューニングしきい値は、オブジェクトがヤング世代に留まることができるヤングコレクションの回数を決定します。以前は、しきい値は増加する傾向がありましたが、減少することは非常にまれでした。これは、持続的に高いしきい値が、サーバイバー領域の大部分を占める古いオブジェクトを残し、それが満杯になったときに若いオブジェクトが早期に昇格するのを強制する可能性があることを意味します。JDK-8380590では、しきい値も減少できるようになり、寿命の長いオブジェクトがより早く昇格し、短命でまもなく死亡する可能性のある若いオブジェクトがヤング世代に保持されるようになります。 Javaヒープが十分なヘッドルームがあっても成長しなかった場合に、繰り返しの大きな割り当てが数千回のFull GCを引き起こした際に、Parallel GCはJavaヒープを正しく拡張するようになりました(JDK-8377561)。 Serial GC Serial GC固有の注目すべき変更はありません。ただし、一部のケースでデフォルトコレクタではなくなったという点を除きます。 すべてのコレクタ すべてのコレクタに、いくつかの興味深い変更がありました。 TLABサイジングは、多くの短命で軽量な割り当てを行うスレッドを作成するアプリケーションをより適切に処理するようになりました。これにより、TLABの過剰サイジングによる無駄の増加と、コレクション数の増加が回避されます(JDK-8381834)。 JDK-8372348は、文字列の重複排除のロギングとJFRイベントを改善しました。ロギングには「新しい未知の」文字列が追加され、より意味のある集計バイト数が提供されます。 次のステップ 私たちの焦点は、自動ヒープサイジングにあり、メモリ管理のさまざまな側面の制御を改善することで、G1が外部条件とユーザーの意図によりインテリジェントに応答できるようにすることです。 感謝 いつものように、JDKのリリースに貢献してくれたすべての人々に感謝します。最後に、いくつかの主要なリファクタリング(Atomic<T>)が完了したことで、他の項目により多くの時間を割くことができるようになりました。次の、おそらくさらに大きなリリースでお会いできるのを楽しみにしています。 トーマス