この記事はNTTドコモソリューションズ Advent Calendar 2025 16日目の記事です。
はじめに
こんにちは、NTTドコモソリューションズで Java/OpenJDK エンジニアをしている坂本統と申します。
2025年9月に最新の LTS バージョンである OpenJDK 25 がリリースされ、様々な新機能を試す方が増えていると思います。特に Project Leyden によって導入された AOT Cache は Java アプリケーションの弱点であった起動時間の遅さを改善できる待望の機能です。Java 25 以降の Java アプリケーションで起動時間の速さが要求されるコンテナワークロードやサーバーレス向けのシステムには必須となると考えます。
昨今は Spring Boot を使って Web アプリケーションを実装することが人気ですが、実は AOT Cache を適用して最大限効果を発揮するにはいくつかテクニックが必要です。これは AOT Cache の JEP には記載されていませんので、Spring Boot のドキュメントもチェックしていないと気づきにくいでしょう。加えて Spring Boot には AOT Cache 同様に起動時間を改善できる Spring AOT という機能があります。AOT Cache と Spring AOT は組み合わせることができ、さらに起動時間を短くすることができます。
本記事では Spring Boot アプリケーション向けに AOT Cache と Spring AOT を適用させる方法と、その性能例として起動時間がどのように改善されたかを紹介いたします。
環境
検証に利用した環境をまとめます。
- Ubuntu 22.04.5 LTS
- Intel Core i7-10710U
- DDR4 64GB
JDK は Oracle OpenJDK 25.0.1 を、アプリケーションは Spring PetClinic を使用しました。
JAR 展開
Spring Boot アプリケーションは多くの場合1つの JAR ファイル(Executable Jar)としてビルドされます。この JAR ファイルを展開するだけで起動が早くなります。このテクニックは Spring Boot 公式でドキュメント化された広く知られたノウハウ(Efficient Deployments - Unpacking the Executable jar)です。
ここでは Spring PetClinic がビルド済みで、ビルドした成果物である target/spring-petclinic.jar という JAR ファイルがあるとします。JAR を展開するには以下のコマンドを実行してください。
$ java -Djarmode=tools -jar target/spring-petclinic.jar extract
この結果、spring-petclinic/spring-petclinic.jar という展開された JAR ファイルが生成されます。このファイルを起動すると、同じアプリケーションが実行されますが、起動時間が短縮されます。
$ java -jar spring-petclinic/spring-petclinic.jar
私の環境では、JAR 展開なし(Executable Jar)の場合 5.181 秒、JAR 展開あり(Unpacked)だと 4.118 秒の起動時間になりました。下記のグラフは内訳として JVM とアプリケーションの起動時間も示していますが、いずれも早くなっていることが分かります。
AOT Cache
次に AOT Cache を適用してみましょう。AOT Cache は既存の AppCDS 機能の発展で、その使用方法はとても似ています。
まずトレーニングとキャッシュ作成を行います。これは一度アプリケーションを立ち上げ、起動時に必要なクラスのロード&リンクと JIT プロファイルを学習(トレーニング)し、そこからキャッシュを生成するステップです。Java 起動オプションに -XX:AOTCacheOutput=app.aot を指定することで、トレーニング実行と、アプリケーションの終了時に指定されたファイルパスへキャッシュを作成します。
ここで重要なテクニックは、前項で展開した JAR ファイルを使用することです。展開した JAR ファイルを使ったトレーニングはそうでない場合に比べより起動時間が早くなるキャッシュを作成することができます。基本的にこれらはセットで実行することを推奨します。
以下のコマンドを実行して、トレーニングとキャッシュ生成を行ってください。
$ java -XX:AOTCacheOutput=app.aot -Dspring.context.exit=OnRefresh -jar spring-petclinic/spring-petclinic.jar
-Dspring.context.exit=OnRefresh を指定することでアプリケーションが起動してまもなく自動で終了します。トレーニングとキャッシュ作成を自動実行する場合に便利です。
このコマンドの実行により AOT キャッシュファイル(app.aot)が生成されます。参考までに私の環境では Spring PetClinic のトレーニングで 121MB のキャッシュファイルが生成されました。
このキャッシュファイルを使用することでアプリケーションの起動時間が早くなります。キャッシュを使用するには Java 起動オプションに -XX:AOTCache=app.aot を指定します。
以下のコマンドでアプリケーションを起動してください。
$ java -XX:AOTCache=app.aot -jar spring-petclinic/spring-petclinic.jar
私の環境では、JAR 展開 + AOT Cache (AOT Cache)で 1.741 秒まで短縮しました。内訳をみるとアプリケーション(app)の起動時間が改善されていることが分かります。
Spring AOT
最後に Spring AOT を適用してみましょう。Spring AOT は GraalVM Native Image をサポートするために追加された機能ですが、Java アプリケーションにも適用できます。
Spring AOT を適用するには、Maven を使用したビルドで追加の設定が必要です。Spring Boot Maven Plugin に Spring AOTの設定をします。以下のように spring-boot-maven-plugin に process-aot のゴールを追加してください。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
Spring PetClinic は Spring Boot Maven Plugin 設定が含まれています。以下のパッチを当ててください。
diff --git a/pom.xml b/pom.xml
index ae930ae..1990702 100644
--- a/pom.xml
+++ b/pom.xml
@@ -235,10 +235,12 @@
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
+ <id>process-aot</id>
<!-- Spring Boot Actuator displays build-related information
if a META-INF/build-info.properties file is present -->
<goals>
<goal>build-info</goal>
+ <goal>process-aot</goal>
</goals>
<configuration>
Spring AOT 設定が完了したら Maven でビルドしてください。特別なビルドオプションなどはありません。以下は Spring PetClinic のビルド例です。
$ ./mvnw package
Spring AOT が適切に設定されると、ビルド成果物として target/spring-aot ディレクトリが生成されます。この中には Spring AOT によって変換されたクラスファイル、ソースファイル、その他リソースファイルが含まれます。
Spring AOT を有効化するには、起動時にシステムプロパティ -Dspring.aot.enabled=true を指定します。Spring AOT はコードを事前変換するので、有効化することで実行コードも変わりますから、トレーニングとキャッシュ作成もやり直す必要があります。JAR 展開 + AOT Cache + Spring AOT をすべて含めたトレーニングとキャッシュ作成のコマンドは以下の通りです。
$ java -XX:AOTCacheOutput=app2.aot -Dspring.aot.enabled=true -jar spring-petclinic/spring-petclinic.jar
JAR 展開 + AOT Cache + Spring AOT をすべて含めた実行コマンドは以下の通りです。
$ java -XX:AOTCache=app2.aot -Dspring.aot.enabled=true -jar spring-petclinic/spring-petclinic.jar
私の環境では、JAR 展開 + AOT Cache + Spring AOT (AOT Cache + Spring AOT)で 1.304 秒まで短縮しました。内訳をみるとアプリケーション(app)の起動時間がさらに改善されていることが分かります。
まとめ
2025年9月にリリースされた JDK 25 では、起動時間の短縮を目的とする Project Leyden の成果である AOT Cache が実装されました。
Spring Boot アプリケーションの起動時間改善にも AOT Cache は有効です。また JAR 展開と組み合わせると AOT Cache の効果が最大限発揮されます。さらに Spring AOT も組み合わせることでさらに起動時間を改善できます。Spring PetClinic の例では、これらの機能を利用することで 5.181 秒から 1.304 秒まで(約 75%)短縮することができました。
JAR 展開と AOT Cache はアプリケーションのソースコード改修なしに簡単に適用可能です。ただし Spring AOT のみライブラリやフレームワーク側の対応と前述の様なビルド設定が必要であることに注意してください。コンテナワークロードやサーバーレスなどの起動時間の短縮が要求される環境では、これらの機能を適用することをおすすめします。
参考
出展:Ana-Maria Mihalceanu, Moritz Halbritter "Supercharge your JVM Performance with Project Leyden and Spring Boot" https://youtu.be/izLzgnMMjbU (参照日:2025年12月1日)
記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。


