Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Spring Boot における​ AOT Cache 活用テクニックと​ 起動時間改善事例​

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Spring Boot における​ AOT Cache 活用テクニックと​ 起動時間改善事例​

JJUG CCC 2026 Spring の発表資料です。

More Decks by NTTドコモソリューションズ Java担当

Other Decks in Technology

Transcript

  1. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    Spring Boot における AOT Cache 活用テクニックと 起動時間改善事例 2026/05/30(Sat) JJUG CCC 2026 Spring NTTドコモソリューションズ株式会社 資料はこちら @speakerdeck.com (ntt_dsol_java)
  2. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    1 自己紹介 名前:坂本 統(さかもと おさむ) ◼ NTT ドコモソリューションズに所属 ◼ Java/OpenJDK エンジニア ◼ 過去に何度か JJUG CCC で発表させていただきました ◼ 本日+過去の資料置き場 speakerdeck.com/ntt_dsol_java
  3. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    2 本日のお話 OpenJDK 24/25 で導入された AOT Cache の基礎と活用テクニックを紹介 ◼ AOT Cache 概要 ◼ AOT Cache 活用テクニック ◼ 性能改善例 ◼ スタートアップ ◼ ウォームアップ
  4. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    4 Java を取り巻く環境の変化 Java の起動時間の遅さがパフォーマンス上の問題として顕在化 [凡例] スタートアップタイム ウォームアップタイム アプリケーションライフタイム サーバ コンテナ サーバレス 起動後は動かしっぱなし ⇒スタートアップ・ウォームアップタイムは あまり課題にならない 必要な量に応じてコンテナを起動/停止 ⇒コンテナ起動毎にスタートアップ・ ウォームアップが発生 ⇒処理開始&ピーク性能までに時間がかかる イベントに応じて処理を起動/停止 ⇒処理毎にスタートアップ・ウォームアップが発生 ⇒処理開始&ピーク性能までに時間がかかる ⇒短いライフタイムではウォームアップが 実行されないことも 昨今の Java App のライフサイクルは短くなる傾向であり、Java の起動時間(スタートアップ)やピーク性能 に至るまでの時間(ウォームアップ)はパフォーマンスに影響する
  5. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    5 JVM 関連の起動高速化技術 大きく分類して4種類の技術あり 技術 概要 起動時間 適用難易度 GraalVM Native Image Java コードを静的解析&変換してネイ ティブバイナリ化する ◎ 高速 × 難しい(ビルド時間長い、ライブラリ 制約強い、デバッグ難易度高い) CRaC 実行中の JVM 状態のスナップショッ トを取得し、それを復元することで高 速化 ◎ 高速 △ やや難しい(JDK やプラットフォーム に制限あり、チェックポイントに対応 したコード実装が必要) AOT Cache Java 起動時処理の一部を事前に学習し キャッシュ化することで高速化 CDS/AppCDS の発展機能 〇 そこそこ高速 ◎ 簡単(JDK 25 以降で利用可) 制限緩い&コード改修不要! CDS(AppCDS) AOT Cache の前身機能 ※ AOT Cache とは併用不可 △ やや高速 ◎ 簡単(JDK 21 以前で利用可) Java 実行環境の OpenJDK/GraalVM は JVM の起動時処理の高速化を進めている 特に AOT Cache は起動時間がそこそこ早くなりつつ利用制限が緩くソースコード改修も不要である点が利点
  6. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    6 AOT Cache とは スタートアップ&ウォームアップ時間を早くする OpenJDK 機能 Java 起動時の処理の一部を事前(Ahead-Of-Time:AOT)実行してキャッシュ(AOT Cache)化することで、 スタートアップ&ウォームアップ時間を早める。CDS が発展した機能で JDK 24/25 から利用可能 Jar ファイル スキャン クラスファイル の読込&解析 JVM 起動時のクラス読み込み関連処理順序(イメージ) ▪スタートアップ時間の高速化(JEP 483: AOT Class Loading & Linking) 同じ App なら基本的に常に同じ起動処理を繰り返すので、事前にクラスオブジェクトのロード&リンクまで実行した結果をキャッシュにして次回起動で利用する CDS Archive AOT Cache ▪ウォームアップ時間の高速化(JEP 515: AOT Method Profiling) 同じ App なら基本的に常に同じ起動時メソッド呼び出しを繰り返すので、事前にプロファイルした情報もキャッシュに含めて次回起動で利用する App 起動時の JIT コンパイラ関連処理順序(イメージ) AOT Cache いつも同じクラス読み込み 最適化されたメソッドB コードの利用開始 いつも同じメソッド呼び出し ※最適化済みコードまでのキャッシュは開発中 JEP draft: Ahead-of-Time Code Compilation ホットメソッドAの プロファイリング 最適化されたメソッドA コードの利用開始 ホットメソッドAの コンパイル ホットメソッドBの プロファイリング ホットメソッドBの コンパイル
  7. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    7 (1)トレーニング&アセンブリ キャッシュ出力先を –XX:AOTCacheOutput ※1で指定し、起動完了後に App を停止させる※2 JVM 停止処理でキャッシュがアセンブリされ、キャッシュファイル(app.aot)が出力される (2)本番実行 上記で作成したキャッシュファイルを –XX:AOTCache で指定して実行(スタートアップ高速化) AOT Cache 利用方法 トレーニング&アセンブリと本番実行の2ステップ $ java -XX:AOTCacheOutput=app.aot –cp … $ java -XX:AOTCache=app.aot –cp … 【参考】AppCDS 利用方法 (1)トレーニング&アーカイブ作成 アーカイブ出力先を -XX:ArchiveClassesAtExit で指定し、起動完了後に App を停止させる JVM 停止中にアーカイブファイル(app.jsa)が出力される (2)本番実行 上記で作成したアーカイブファイルを -XX:SharedArchiveFile で指定して実行(スタートアップ高速化) $ java -XX:ArchiveClassesAtExit=app.jsa –cp … $ java -XX:SharedArchiveFile=app.jsa –cp … ※1 このオプションは JDK 25 か ら利用可能 ※2 JDK 25.0.4 で jcmd に AOT.end_recording が追加され ることで App 停止しなくても キャッシュ作成が可能になる
  8. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    8 AOT Cache 利用時の注意 トレーニングと本番実行の環境は一致させること AOT Cache は(アプリケーションに変更がなければ)起動時の処理は毎回同じことをするという前提 トレーニングと本番で環境や実行コードに違いがあると改善効果が小さくなるか通常起動にフォールバックする 以下の制約に従って、トレーニングと本番実行の環境は一致させること ⚫ アプリケーションの変更禁止 ⚫ 再ビルドしたらトレーニングのやり直しが必要 ⚫ JDK や OS、CPU アーキテクチャなどの環境を変更しない ⚫ JDK はバージョンレベルも完全一致させること ⚫ クラスパスやモジュールオプションは変更禁止 ⚫ メインクラスは変更OK ⚫ JVMTI エージェント(クラス書換やクラスロード操作 API)は利用不可 ⚫ クラウドプロバイダの監視系エージェントの利用などで注意 ⚫ GC 方式は例外的に変更可能 ⚫ ZGC 対応は JDK 26 から(JEP 516)
  9. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    10 Spring Boot の AOT Cache 利用 Fat Jar は展開してからトレーニングすること Maven や Gradle で Spring Boot App をビルドすると成果物が Fat Jar ※1になる クラウドやコンテナでも可搬性やクラスパスの煩雑さ回避の目的で Fat Jar のまま起動すると便利 ただし Spring Boot は Fat Jar を展開しないと起動が遅くなることは広く知られている※2 さらに AOT Cache や AppCDS は Jar 展開してからトレーニングをしないと改善性能が低くなる※3 以下のコマンドで Jar ファイルを展開してからトレーニング&本番起動すること # Spring Boot の機能で Jar を展開※4 $ java -Djarmode=tools -jar /path/to/app.jar extract --destination /path/to/extracted # 展開した Jar を実行 $ java -jar /path/to/extracted/app.jar ※1 アプリケーションコード、依存関係ライブラリ、ランチャーなどが含まれる自己完結型の Jar ファイルで、java -jar app.jar だけで実行可能 ※2 Fat Jar は Spring Boot のカスタムクラスローダーを使ってクラスを読み込むためコストがかかる。Jar 展開するとカスタムクラスローダを使わなくなり、 ディレクトリやワイルドカードを使用しないフラットなクラスパスを指定することと同じになり、JVM がクラスを直接読み込むため早くなる ※3 AOT Cache はカスタムクラスローダに対応していないため展開しないとすべてのクラスをキャッシュできないため改善性能が低くなる ※4 このコマンドは Spring Boot の機能によるもので、アプリケーションコードだけの app.jar と依存ライブラリ群を含む extracted/lib ディレクトリに展開する。 app.jar には lib 内のライブラリを参照するマニフェストが含まれるため、これを -jar で指定するだけで起動できる
  10. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    11 AOT Cache 適用例(適用手順の確認) Spring PetClinic を Jar 展開して AOT Cache を適用する手順例 # spring-petclinic ホームディレクトリで Maven Wrapper を使ってビルド $ ./mvnw package # Fat Jar の展開 $ java -Djarmode=tools -jar target/spring-petclinic-4.0.0-SNAPSHOT.jar ¥ extract --destination target/extracted # トレーニング&アセンブリ # -Dspring.context.exit=onRefresh を指定すると App 起動後に自動停止 $ java -Dspring.context.exit=onRefresh -XX:AOTCacheOutput=app.aot ¥ -jar target/extracted/spring-petclinic-4.0.0-SNAPSHOT.jar # 本番実行 $ java -XX:AOTCache=app.aot -jar target/extracted/spring-petclinic-4.0.0-SNAPSHOT.jar … 2026-05-25T18:57:07.524+09:00 INFO 781541 --- [ main] o.s.s.petclinic.PetClinicApplication : Started PetClinicApplication in 1.432 seconds (process running for 1.69)
  11. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    12 (参考)Spring AOT の利用 スタートアップ高速化&メモリフットプリント削減できるフレームワークの機能 Spring AOT は アプリケーションコードを静的解析して最適な形へ事前変換する機能 簡単に言えばリフレクションなどの動的要素を削除したコードへ変換することでスタートアップを高速化する AOT Cache と Spring AOT は全く別の機能であるため併用可能 AOT Cache と Spring AOT を組み合わせることでさらにスタートアップを高速化できる ただし、もともと GraalVM Native Image をサポートするために実装された機能であり、App で利用するフ レームワークやライブラリが Spring AOT に対応していないと利用不可なため適用難易度は高い Spring AOT を利用するには以下の2つを設定する 詳細は公式ドキュメントを参照すること 1. Spring Boot Maven Plugin で process-aot を有効化してビルド 2. システムプロパティ-Dspring.aot.enabled=true を指定して App を実行
  12. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    13 0.00 1.00 2.00 3.00 4.00 5.00 6.00 Baseline Extracted Extracted + AOT Cache Extracted + AOT Cache + Spring AOT Extracted + AppCDS Extracted + AppCDS + Spring AOT Spring PetClinic Startup Time(sec) jvm app AOT Cache 適用例(スタートアップ時間確認) Spring PetClinic に Jar 展開 + AOT Cache を適用するとスタートアップ時間が大幅短縮 ▪実行環境 • Ubuntu 24.04.4 LTS • Oracle OpenJDK 25.0.2 • Spring PetClinic (Commit a6efbed) • Intel Core i7-10710U CPU @ 1.10GHz, 12 cores • DDR4 32GBx2(最大 Java ヒープサイズ 16GB) 5.10 4.08 1.67 1.25 (補足)Baseline: Jar 展開なし、Extracted: Jar 展開あり、AOT Cache: AOT Cache 利用、AppCDS: AppCDS 利用、Spring AOT: Spring AOT 利用 Jar 展開 + AOT Cache を適用すると Baseline 比でスタートアップ時間が 67% 短縮 Jar 展開 + AOT Cache + Spring AOT を適用すると Baseline 比でスタートアップ時間が 75% 短縮 2.36 1.79 AOT Cache 【参考】AppCDS AppCDS もそこそこ改善
  13. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    14 コンテナ環境での AOT Cache 利用 Jar 展開 + トレーニング + 本番実行までを一括して実行するビルド構成パターン Spring Boot 公式ドキュメントの AOT Cache サンプル(下記)に従って Dockerfile を作成すればよい FROM bellsoft/liberica-openjre-debian:25-cds AS builder WORKDIR /builder ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} application.jar RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted FROM bellsoft/liberica-openjre-debian:25-cds WORKDIR /application COPY --from=builder /builder/extracted/dependencies/ ./ COPY --from=builder /builder/extracted/spring-boot-loader/ ./ COPY --from=builder /builder/extracted/snapshot-dependencies/ ./ COPY --from=builder /builder/extracted/application/ ./ RUN java -XX:AOTCacheOutput=app.aot -Dspring.context.exit=onRefresh -jar application.jar ENTRYPOINT ["java", "-XX:AOTCache=app.aot", "-jar", "application.jar"] Jar 展開用に builder イメージを設定 Fat Jar をローカルからコピー Fat Jar を展開 Builder イメージから展開した Jar ファイル一式をコピー トレーニングを実行 起動した後自動で停止するシステムプロパティ 展開後の Jar を実行 キャッシュを利用して本番実行 展開後の Jar を実行 ※ Spring Boot の Cloud Native Buildpacks サポートと Paketo Java ビルドパックは AOT Cache をサポートしているので、これを利用すれば上記の構成を含めた Docker イメージの作成 まで一括して実行可能。詳しくは公式ドキュメントを参照すること
  14. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    16 性能検証対象アプリケーション 弊社開発サンプル App を使った AOT Cache の性能測定結果を共有 スタートアップ&ウォームアップ性能サンプルとして Airline Ticket Reservation System(ATRS) の Spring Boot 版へ AOT Cache を適用して検証した結果を共有する ATRS(Spring Boot 版) トップ画面 • 航空券予約システムを模したサンプル Web App • ATRS は Macchinetta フレームワークのコミュニ ティが作成したリファレンス実装 • Spring Boot 版は弊社が独自開発したもので Macchinetta 公式ではない • Spring AOT は適用不可(未対応)
  15. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    17 スタートアップ スタートアップ性能は CPU リソースが影響するためコンテナ環境で CPU limits(1/2/4/8) をかけて検証を実施 CPU 2/4/8 の環境では Baseline と比較して 50%、AppCDS と比較しても 25% 程度早くなった (補足) • コンテナ(Docker)ホストマシンは Spring PetClinic 性能測定の実行環境と同じ • コンテナイメージは amazoncorretto:25-al2023-jdk(Amazon Corretto 25.0.3.9.1) を使用 • Memory limits 4GB/JavaHeap 2GB/Metaspace 512MB/CCS 128MB を指定 ※これらの違いによる有意な起動時間差異が確認できなかったため値は固定 • いずれも Jar 展開済み AOT Cache により 50% 程度スタートアップ時間が早くなった 17.96 15.35 12.48 6.76 4.43 3.44 5.08 3.31 2.53 5.11 3.31 2.45 0.00 5.00 10.00 15.00 20.00 Baseline AppCDS AOT Cache Baseline AppCDS AOT Cache Baseline AppCDS AOT Cache Baseline AppCDS AOT Cache 1 2 4 8 Sample App Starup Time(sec) (10time-average) jvm app CPU limit
  16. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    18 ウォームアップの準備 特定処理に対して負荷をかけ続けた後のプロファイリング情報をキャッシュ化 ウォームアップを確認するため特定のメソッドがピーク性能に至るまでの時間を測定する ピーク性能に達したかどうかは、ツールを使って特定のメソッドを実行する処理(URL)へ負荷をかけ続けて、 レスポンスタイムを見て判断することとした トレーニングについては起動直後に App を停止するのではなく、特定処理へ負荷をかけ続けピーク性能に達し たことを確認してから停止することでアセンブリした ATRS サーバ App のライフタイム 開始 停止 Tomcat 起動 ウォームアップ (レスポンス) 負荷ツール (Vegeta) 負荷実行 (リクエスト) 停止処理 (アセンブリ) レスポンス タイム 経過時間 レスポンスタイムの下限 =ピーク性能 負荷
  17. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    19 ウォームアップ(結果) ピーク性能に至るまでの時間は 20~60% 程度早くなったことを確認 負荷トレーニングなし 負荷トレーニングあり 16.1s Elapsed time(sec) Response Time 4つの処理すべてでウォームアップ時間が改善 ただしキャッシュファイルも1処理あたり 20MB 増加 ウォームアップ時間が 48% 改善した例(B:フライト検索結果表示) Response Time Elapsed time(sec) 8.4s 処理 負荷トレーニング なしのピーク性能 到達時間(秒) 負荷トレーニング ありのピーク性能 到達時間(秒) 改善率 起動直後と比較した キャッシュファイル サイズ増加量 A 6.2 4.9 21% 13MB B 16.1 8.4 48% 20MB C 11.8 8.8 25% 20MB D 4.3 1.6 63% 17MB (補足) • 検証環境(ATRS サーバ)はSpring PetClinic 性能測定の実行環境と同じ • A~Dの処理は個別に負荷をかけてトレーニング&アセンブリを実施 • 負荷学習なしは起動直後までトレーニングした AOT Cache を利用 • いずれも Jar 展開済み
  18. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    20 まとめ AOT Cache を利用すると App のスタートアップとウォームアップ時間が改善 • JDK 25 から AOT Cache が利用可能に • 利用の制限が緩くソースコード改修も不要なので今すぐスタートアップを早くしたい場合に有効 • 使い方は簡単な2ステップ • -XX:AOTCacheOutput オプションでトレーニング&アセンブリ • -XX:AOTCache オプションで本番実行 • Spring Boot アプリケーションで利用する場合は Jar 展開が必須 • java -Djarmode=tools –jar app.jar extract ... • Jar 展開してからトレーニングをすること! • Jar 展開 + AOT Cache でスタートアップが早くなる • だいたい 50% 程度早くなった • Jar 展開 + AppCDS もそこそこ早くなるので JDK 21 以前にはオススメ
  19. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    21 参考文献 ⚫ Project Leyden https://openjdk.org/projects/leyden/ ⚫ JEP 483: Ahead-of-Time Class Loading & Linking https://openjdk.org/jeps/483 ⚫ JEP 514: Ahead-of-Time Command-Line Ergonomics https://openjdk.org/jeps/514 ⚫ JEP 515: Ahead-of-Time Method Profiling https://openjdk.org/jeps/515 ⚫ JEP 516: Ahead-of-Time Object Caching with Any GC https://openjdk.org/jeps/516 ⚫ JEP draft: Ahead-of-Time Code Compilation https://openjdk.org/jeps/8335368 ⚫ JDK-8370203: Add jcmd AOT.end_recording diagnostic command https://bugs.openjdk.org/browse/JDK-8370203 ⚫ Inside Java - Supercharge your JVM Performance with Project Leyden and Spring Boot https://inside.java/2025/11/02/devoxxbelgium-leyden-supercharge-jvm-performance/ ⚫ Inside Java - Run Into the New Year with Java’s Ahead-of-Time Cache Optimizations https://inside.java/2026/01/09/run-aot- cache/ ⚫ JVM Weekly - "Diagnosing Your Leyden AOT Cache" with María Arias de Reyna Domínguez https://www.jvm- weekly.com/p/diagnosing-your-leyden-aot-cache ⚫ Spring Boot Reference - Efficient Deployments https://docs.spring.io/spring-boot/reference/packaging/efficient.html ⚫ Spring Boot Reference - AOT Cache https://docs.spring.io/spring-boot/reference/packaging/aot-cache.html ⚫ Spring Boot How-to Guides - AOT Cache https://docs.spring.io/spring-boot/how-to/aot-cache.html ⚫ Spring Boot Build Tool Plugins - Ahead-of-Time Processing https://docs.spring.io/spring-boot/maven-plugin/aot.html ⚫ Unpacking Spring Boot JARs: A Guide to Faster Deployment https://runebook.dev/en/docs/spring_boot/deployment/deployment.efficient.unpacking
  20. © NTT DOCOMO SOLUTIONS, Inc. 2026 NTT DOCOMO SOLUTIONS, Inc

    22 Q&A 本日(+過去)の資料置場 speakerdeck.com/ntt_dsol_java 全体 アンケート セッション アンケート