JEP 544はHotSpotのAOTキャッシュに最適化済みネイティブコードを加える

JEP 544「Ahead-of-Time Code Compilation」は、訓練実行で選ばれたメソッドをネイティブコードへコンパイルし、既存のAOTキャッシュへ保存する提案である。 本番実行では保存済みコードを起動直後から読み込めるため、HotSpotが実行のたびにインタープリター、プロファイリング、JITコンパイルを経てピーク性能へ到達するまでの時間を短縮できる。

HotSpotそのものについてはhotspot-is-an-adaptive-jvm-implementationに分けた。

https://openjdk.org/jeps/544

この提案は静的コンパイル済みの単体実行ファイルを作るものではない。 HotSpotは同じ実行の中でAOTコードとJITコードを併用し、訓練時と異なる負荷が現れれば、AOTコードを最適化解除して現在の負荷に合うコードをJITコンパイルする。 これにより、事前コンパイルの速い立ち上がりと、JITコンパイルの実行時適応を両立させる。

Project Leydenの積み重ね

JEP 544は、Project Leydenが段階的にAOTキャッシュへ移してきた処理の続きに位置する。 JEP 483はJDK 24でクラスの読み込みとリンク結果を保存し、JEP 515はJDK 25でメソッドの実行プロファイルを保存した。 JEP 544は次の段階として、プロファイルを使って生成した最適化済みネイティブコードそのものを保存する。

https://openjdk.org/jeps/483

https://openjdk.org/jeps/515

既存の一段階の手順は変わらない。

java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App
java -XX:AOTCache=app.aot -cp app.jar com.example.App

内部では、観測結果をAOT構成へ記録する段階と、そこからAOTキャッシュを組み立てる段階に分かれる。 後者でネイティブコードが生成されるが、通常はAOTCacheOutputが二段階目を透過的に実行する。

保存済みコードを使えない場合

AOTコードにはプロセッサ命令とガベージコレクター固有の読み書き障壁が含まれる。 このため、訓練実行と本番実行では、CPUアーキテクチャと機能の組み合わせ、およびガベージコレクターを一致させる必要がある。 たとえばAVX-512を持つx64 CPUで生成したコードは、AVX-512を持たないx64 CPUでは使えない。

条件が一致しなくてもプログラムの正しさは損なわれない。 HotSpotはAOTコードの読み込みを断念してインタープリターとJITコンパイルへ戻り、AOTキャッシュ内の事前リンク済みクラスとプロファイルは引き続き利用する。

訓練時にはクラスが初期化されていないため、AOTコードは実行時のクラス初期化順序やstatic finalフィールドの値を常に決め打ちできない。 クラス初期化が必要なメソッドについては確認処理を持つ遅い版と、初期化後に使う最適化しやすい速い版を生成する。 実行ごとに変わり得るstatic finalフィールドは、AOTコードでは定数として埋め込まず、明示的に読み込む場合がある。

提案に掲載された性能測定

二つのCPUコアを持つLinux/x64環境で、一般的なJavaフレームワークを使う五つのアプリケーションを測定した結果、ネイティブコードを含まない従来のAOTキャッシュは起動時間を約50%から70%短縮し、ネイティブコードを含むキャッシュは約65%から80%短縮した。

javacで同じ50個のソースファイルを20回コンパイルする測定では、最初の反復で従来のAOTキャッシュが約30%、AOTコードの追加がさらに約45%、合計で約75%の改善を示した。 AOTコードを使う場合は4回目の反復までに定常状態へ近づいた。 これらは限られたCPU資源でJITコンパイラーとアプリケーションが競合するマイクロサービス環境を模した測定であり、あらゆるアプリケーションで同じ比率になるという保証ではない。

2026年9月の更新

2026年9月10日の更新で、提案の状態はSubmittedからCandidateへ進み、JEP番号544が割り当てられた。 担当者はMark ReinholdからJohn Roseへ移り、翌日にVladimir Kozlovによる承認と実装用CSRへの関連付けが記録された。

https://bugs.openjdk.org/browse/JDK-8335368

候補化の直前には説明も整理された。 目標には、アプリケーション、ライブラリ、フレームワークのコード変更を不要にすること、AOTキャッシュを指定する以外のHotSpot設定変更を不要にすること、Serial、Parallel、G1、ZGCを継続して扱うこと、AOTコードからJITコードへの移行をアプリケーションから見えなくすることが明記された。 9月1日には起動時間とウォームアップ時間を分けた測定資料と生データが添付され、本文の性能節もその結果に合わせて詳しくなった。

候補への昇格は特定のJDKへの搭載決定を意味しない。 2026年9月11日時点では状態はCandidate、対象版は未設定であり、実装課題は未完了、CSRもProvisionalである。

https://bugs.openjdk.org/browse/JDK-8380476

https://bugs.openjdk.org/browse/JDK-8380477

#hotspot #java #aot #jit #project-leyden

Appendix: Work Record

調査日は2026年9月11日、接続先はOpenJDKのJEPページとJava Bug Systemである。 Codex内ブラウザでJEP 544の本文、JDK-8335368のコメント、履歴、関連課題、添付資料の名称と日時を確認した。 端末からの測定コマンドは実行しておらず、性能値はJEP掲載値を転記した。

確認した生の状態は、JEPページのCreatedが2024/06/30 04:47、Updatedが2026/09/10 15:28、StatusがCandidateである。 Java Bug Systemの履歴には、2026年9月10日のSubmittedからCandidateへの変更、JEP番号544の付与、担当者変更、2026年9月11日の承認者追加とCSR関連付けが記録されていた。

履歴画面は大きな本文変更を旧版と新版の全文として表示するため、個々の編集日時における全単語の差分までは保存していない。 本文の更新点は、現在の本文、直近の旧版、コメント、添付資料の日時を比較して分類した。 一時資源は作成しておらず、後片付けは不要だった。