#chiroito ’s blog

Java を中心とした趣味の技術について

アプリを変えず Java の起動時間が 60% 短くなった!

Java 24に導入されたJEP 483: Ahead-of-Time Class Loading & Linkingを試してみました。 この機能は、アプリケーションのクラスをロードおよびリンクされた状態で即座に利用できるようにすることで、起動時間を改善します。

3行で

  • アプリの起動時間のうちクラスローディングとクラスのリンクが支配的な場合は速くなる(実測およそ60%減)
  • アプリの変更は必要なく、キャッシュを作成するだけ。
  • OpenJDKとフレームワークがきちんとサポートするようになったら良さそう。

検証

今回は、マイクロサービスを作るフレームワークであるQuarkusと、Jakarta EEのアプリケーションサーバであるWildFlyで起動速度がどうなるか検証してみます。

現時点では、Quarkus、WildFlyのどちらでも正式にAhead-of-Time Class Loading & Linkingをサポートしていないのでご注意ください。

検証方法は、5回起動し、起動後に表示される起動時間の平均を取りました。

起動方法は、以下の3通りです。

  • 普通にJavaを起動
  • AOTキャッシュ(ロードまたはリンクなし)を使ってJavaを起動
  • AOTキャッシュ(ローディングとリンクを含む )を使ってJavaを起動

起動時間は、ミリ秒で記載しています。 また、Javaを普通に起動したときと比べてどれくらい起動時間が減少したかを赤字で記載しています。

Quarkus

まずはマイクロサービスを作るフレームワークであるQuarkusです。

Quarkusは、普通に起動しても500ミリ秒で起動しました。 その起動時間は、ロードとリンクが無くても半分になり、ロードとリンクがあるとおよそ60%短縮しました!!

WildFly

次に、Jakarta EEのアプリケーションサーバであるWildFlyです。 WildFlyは、普通に起動しても2,400ミリ秒で起動しました。 その起動時間は、ロードとリンクが無くても4.3%短縮し、ロードとリンクがあるとおよそ10.1%短縮しています。

使い方

Ahead-of-Time Class Loading & Linking を使うには、キャッシュを作ります。 このキャッシュを使って、起動すると起動時間が短縮します。

詳しくは JEP を見てください。JEP 483: Ahead-of-Time Class Loading & Linking

キャッシュを作ることをトレーニングと呼びます。 トレーニングは、Javaを2回起動します。 1回目で設定ファイルを作り、2回目で設定ファイルを使ってキャッシュを作ります。

java -XXX:AOTMode=record -XXX:AOTConfiguration=app.aotconf -cp .jar Main
java -XXX:AOTMode=create -XXX:AOTConfiguration=app.aotconf -XXX:AOTCache=app.aot -cp xxx.jar Main

これで、設定ファイル app.aotconf、キャッシュ app.aotができました。

キャッシュを使ってアプリを起動します。ここでは設定ファイルは不要です。

java -XX:AOTCache=app.aot -cp xxx.jar Main

注意事項として、すべての実行は、以下が同じでなければいけません。

  • JDKリリース
  • ハードウェア・アーキテクチャ
  • オペレーティング・システム

まとめ

Javaの起動時間を短縮させる Project Leyden が進み、Java 24ではJEP 483: Ahead-of-Time Class Loading & Linking が導入されました。とはいえ起動速度が短縮する量はアプリケーションにより異なります。起動処理のうち、クラスローディングが支配的なアプリケーションは速くなりますが、それ以外の処理が支配的なアプリケーションでは短縮量が相対的に小さくなりますのでご注意ください。