Compact Object Headers

HotSpot JVMのオブジェクトヘッダを、64bitアーキテクチャで従来の96bit(12バイト)から64bit(8バイト)へ圧縮する機能。ヒープ上の全オブジェクトに付くヘッダを縮めるため、多数の小さいオブジェクトを扱うアプリケーションほど恩恵が大きい。Java 24で実験導入(JEP 450)、Java 25で正式機能化(JEP 519)、Java 27でデフォルト有効化(JEP 534)という3段階を踏んで進化してきた。

従来のオブジェクトヘッダ構造(96bit)

  • Mark Word(64bit): 識別ハッシュコード(31bit) + GC年齢(4bit) + タグビット(2bit) + 未使用領域(27bit)
  • Class Word(32bit): 圧縮クラスポインタ(compressed class pointer)

Compact Object Headersでの新構造(64bit)

Mark WordとClass Wordを64bit1本に統合する。

要素 ビット数
クラスポインタ 22bit
識別ハッシュコード 31bit
[[project-valhalla|Valhalla]]向け予約領域 4bit
GC年齢 4bit
Self Forwarded Tag 1bit
タグビット 2bit

Narrow Klass Pointer(22bit化)の仕組み

クラス情報領域を1,024バイト単位のブロックに分割する。4GB分のクラス情報空間を1,024バイト単位で表現すると4,194,304ブロックとなり、$2^{22} = 4{,}194{,}304$なので22bitで足りる。実際のポインタへ復元する際は、22bitのブロック番号を左に10bitシフトして32bitポインタに戻す。

Self Forwarded Tag

従来のGC実装は、オブジェクトを移動した際にMark Wordを移動先アドレスへのポインタで置き換えていた(forwarding pointer)。しかしCompact Object Headersではその64bit全体にクラスポインタなど他の情報も詰まっているため、Mark Wordを丸ごとポインタで上書きするとクラス情報を失ってしまう。代わりに1bitの新フラグを立てて「自己参照(転送済み)状態」であることだけを示す方式に変更されている。

性能への効果

SPECjbb2015ベンチマークでヒープ使用量22%減・CPU時間8%減。GC回数はG1・Parallel双方で15%減少したとの報告がある。AmazonはJDK 17/21へのバックポート版を含め、数百の本番サービスに導入した結果、リグレッションなしで最大30%のCPU削減を確認したとしている。

既知の制約・非互換

  • Java 26以降、レガシーなStack Locking(旧来のロック実装モード)を再度有効化できなくなった。
  • Java 27以降、Compressed Class Pointers(-XX:-UseCompressedClassPointers)を無効化できなくなった。Compact Object HeadersはCompressed Class Pointersの仕組みに依存しているため。
  • ヘッダ構造にはProject Valhallaの値型対応を見越して4bitの予約領域が確保されている。

出典

#java #openjdk #jvm

作成日時: 2026-08-19 23:01 / 更新日時: 2026-08-19 23:01