spring boot 3 はすでに一定期間リリースされており、公式では GraalVM Native を sp3 の重要な機能として位置づけています。
GraalVM とは何ですか?#
名前からわかるように、GraalVM は仮想マシンであり、主な目標は Java アプリケーションのパフォーマンスを向上させ、リソースをより少なく消費することです。
GraalVM は、Java HotSpot JVM に JIT コンパイラと AOT を追加して、アプリケーションをネイティブ実行可能ファイルにコンパイルすることができます。Java 以外にも、GraalVM は JavaScript、Ruby、Python など、さまざまなプログラミング言語をサポートしています。
簡単に言えば、GraalVM は Java または他の言語をそのインタプリタでバイナリプログラムにコンパイルできます。Spring Boot 3 フレームワークで書かれた Java プログラムが変換されると、起動速度が向上し、メモリ使用量が減少し、最適なパフォーマンスが得られます。
なぜ GraalVM が必要なのですか?#
なぜ Java が GraalVM に注目しているのでしょうか?
Java は古い言語として、新興の技術やトレンドに追いつくことができなくなっています。JDK は常に更新されていますが、歴史的な制約によって制約されています。
その中でも、クラウドネイティブ、サーバーレス、コンテナ化などの新しいトレンドは、Java にとっては大きな課題となっています。まだ完全に死んでいるわけではありませんが、これは将来の大勢であり、阻止することはできません。
サーバーレスについての考察#
サーバーレスのプロバイダー(クラウドサービスプロバイダー)にとって、より小さなメモリ使用量、より高速な起動速度は、コスト削減の必然的な選択肢です。
消費者(企業)にとっては、サーバーの購入と運用の費用を節約できるだけでなく、従量課金もサポートされているため、非常に魅力的です。
また、AI の大規模モデルは業界を再編成していますが、トレーニング、デプロイ、イテレーションの能力を持つのは大企業だけであり、大規模モデルの能力を提供できるのはクラウドサービスプロバイダーだけです。そのため、サーバーレスは中小企業にとって AI との連携の最適な選択肢となります。
GraalVM のインストール#
公式ウェブサイトからダウンロードして展開し、展開後に環境変数を設定する必要があります。
公式の設定方法を使用することができます。
#以下のパスを展開したローカルのパスに変更してください
setx /M PATH "C:\Program Files\Java\graalvm-ce-java11-20.3.0\bin;%PATH%"
setx /M JAVA_HOME "C:\Program Files\Java\graalvm-ce-java11-20.3.0"
または、直接環境変数を設定することもできます。
win
+ i
を押して設定に入り、高度なシステム設定、環境変数に移動し、次の設定を追加します。
GRAALVM_HOME:展開したパス
JAVA_HOME:展開したパス
次に、pathに以下の設定を追加します。
%GRAALVM_HOME%\bin
%JAVA_HOME%\bin
cmd で java -version
コマンドを実行してバージョンを確認し、GraalVM の文字が表示されれば成功です。
コンパイル環境のインストール#
Java を GraalVM でバイナリにコンパイルするには、C++ 環境をインストールする必要があります。
以下はVisual Studioを使用して関連する環境をインストールする方法ですが、公式チュートリアルも参照できます。
Windows 11 の場合、公式チュートリアルの Visual Studio 2019 ではなく、最新バージョンを使用してください。
以下のコンポーネントをインストールします。
spring boot 3 プロジェクトの作成#
IntelliJ IDEA を使用して作成します。
JDK は GraalVM を選択し、Java のバージョンは 17 以上を選択してください。
spring boot 3.0 以上のバージョンを選択し、GraalVM Native Support と Web 依存関係を追加します。
作成が完了したら、pom.xml ファイルに以下のプラグインが含まれていることを確認します。
作成が完了したら、新しいコントローラーを作成し、簡単なインターフェースを記述します。
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("test")
public String test(){
return "hello world";
}
コンパイルとビルド#
コードが書き終わったら、コンパイルします。
Visual Studio Build Tools x64 Native Tools Command Prompt for VS 2022 を開きます。
x64、x86 のどちらでも構いません。次に、プロジェクトディレクトリに移動します。
mvn -PnativeTest test
コマンドを使用してコンパイルテストを実行します。
エラーがない場合は、mvn native:build
コマンドを使用してビルドを実行します。ビルドが完了すると、プロジェクトディレクトリに exe ファイルが生成されます。
ビルド後のファイルサイズはまだ大きいですが、これはビルドプロセスでいくつかの依存関係がパッケージ化されているためです。
そのうち約 50M はコードのサイズであり、この部分には java.base
も含まれています。
30M はイメージのヒープサイズであり、残りはその他のデータです。
exe ファイルを起動すると、非常に高速な速度で起動されることがわかります。
現在の課題#
GraalVM は非常に興味深いものであり、Java がクラウドネイティブに向けて勇敢な試みを行ったものです。Java の重大な欠点を解決しましたが、同時に致命的な問題も引き起こしました。
Java の動的呼び出しはさまざまな依存関係を導入し、呼び出し時に指定されますが、GraalVM Native は静的なコード到達性解析に基づいた AOT(Ahead of Time)を使用しています。言い換えれば、Java のコンパイル時にはあなたが何を使うかはわかりませんが、呼び出し時には見つけることができます。一方、GraalVM ではコンパイル時にはあなたが誰であり、何を使うのかを指定する必要があります。
GraalVM はコンパイル時間を犠牲にして起動時間を最適化しました。これは正しいアプローチですが、動的な呼び出しはできなくなります。
反射を使用して解決する方法も提供されていますが、現時点では非常に複雑です。
私は MyBatis の依存関係を導入しましたが、使用していませんが、テストのコンパイルに失敗しました。
在 spring boot3 中使用 native image
Using GraalVM and Native Image on Windows 10