GraalVMダッシュボードを使用したネイティブ実行可能ファイルのサイズの最適化
GraalVMダッシュボードは、ネイティブ実行可能ファイルの構成を視覚化するWebベースのツールです。ネイティブ実行可能ファイルに含まれるパッケージ、クラス、およびメソッドの内訳を表示し、そのヒープ・サイズに最も影響を与えているオブジェクトのサマリーを視覚的に提供します。GraalVMダッシュボードでは、ネイティブ・イメージ・ビルダーによって作成されたレポート・ファイルが使用されます。(詳細は、GraalVMのスタート・ガイドを参照してください。)
このガイドでは、ダッシュボードを使用してネイティブ実行可能ファイルのサイズを最適化する方法を示します。従来のfortune
Unixプログラムをシミュレートする"fortune"サンプル・アプリケーションの2つの実装が導入されています(詳細は、fortuneを参照してください)。
ノート: このガイドでは、Mavenがインストールされていることを前提としています。
Fortune
最初の実装(fortune)の内容をネイティブ実行可能ファイルとしてパッケージ化し、その構成を確認します。
-
GraalVM JDKがインストール済であることを確認します。最も簡単に始めるには、SDKMAN!を使用します。その他のインストール・オプションについては、「ダウンロード」セクションを参照してください。
- リポジトリをダウンロードまたはクローニングし、fortune-demo/fortuneディレクトリに移動します:
git clone https://github.com/graalvm/graalvm-demos
cd fortune-demo/fortune
- プロジェクトをビルドします:
mvn clean package
- ビルドが成功したら、トレース・エージェントを使用してJVMでアプリケーションを実行します。GraalVMをインストールしたため、GraalVM JDKで実行されます。
mvn -Pnative -Dagent exec:exec@java-agent
アプリケーションはランダムなメッセージを返します。エージェントは、
target/native/agent-output
サブディレクトリに構成ファイルを生成します。 - GraalVMネイティブ・イメージおよびMavenを使用して、このアプリケーションのネイティブ実行可能ファイルをビルドします:
mvn -Pnative -Dagent package
コマンドが完了すると、ネイティブ実行可能ファイル
fortune
がプロジェクトの/target
ディレクトリに生成され、使用できるようになります。 - ネイティブ実行可能ファイルを直接起動してアプリケーションを実行します:
./target/fortune
アプリケーションはランダムなフレーズをゆっくりと出力します。
アプリケーションのpom.xmlファイルは、ネイティブ・イメージMavenプラグインを使用してネイティブ実行可能ファイルをビルドします。次の2つのオプションを使用して診断データを生成するように構成されます:
-H:DashboardDump=fortune -H:+DashboardAll
これらのオプションにより、fortune.bgvという名前のファイルが生成されます。(様々なオプションの詳細は、GraalVMダッシュボードのデータのダンプに関する項を参照してください。)
JARファイルとネイティブ実行可能ファイルのサイズを比較します(
du
の使用など):du -sh target/* 0B target/archive-tmp 136K target/classes 17M target/fortune 2.0M target/fortune-1.0-jar-with-dependencies.jar 32K target/fortune-1.0.jar 44M target/fortune.bgv 4.0K target/fortune.build_artifacts.txt 0B target/generated-sources 4.0K target/maven-archiver 8.0K target/maven-status 0B target/test-classes
ネイティブ実行可能ファイルのサイズが17MBであるのに対し、JARファイルのサイズは2MBです。サイズが増加するのは、ネイティブ実行可能ファイルに必要なすべてのランタイム・コードと事前に初期化されたデータがヒープに含まれているためです。
-
GraalVMダッシュボードを開き、fortune.bgvファイルをロードします。(「+」をクリックし、「ファイルの選択」をクリックして、targetディレクトリからfortune.bgvファイルを選択し、「OK」をクリックします。)
GraalVMダッシュボードには、ネイティブ実行可能ファイルを視覚化したものが2つ(コード・サイズの内訳とヒープ・サイズの内訳)表示されます。(詳細は、コード・サイズの内訳に関する項およびヒープ・サイズの内訳に関する項をそれぞれ参照してください。)
上のスクリーンショットは、
fortune
ネイティブ実行可能ファイルのコード内訳を視覚化したもので、その大部分は、パッケージcom.fasterxml
に実装されているJackson JSONパーサー・ライブラリで構成されています。ネイティブ実行可能ファイルのサイズを減らす方法の1つは、コードが占める容量を最小限に抑えることです。コード・サイズの内訳によって、ネイティブ実行可能ファイルに含まれるパッケージが占める容量を把握できます。さらに、下のスクリーンショットは、ネイティブ実行可能ファイルのヒープに4MBのバイトとほぼ800KBの文字列が含まれていることを示しています。ネイティブ実行可能ファイルのサイズを減らすもう1つの方法は、ヒープのサイズを最小化することです。
次の項では、コードの量を減らし、ヒープのサイズを小さくする
fortune
アプリケーションの代替実装について検討します。
静的Fortune
fortuneアプリケーションの最初の実装では、Jackson JSONパーサー (パッケージcom.fasterxml
)を実行時に使用して、ネイティブ・イメージ・ビルダーがネイティブ実行可能ファイルに含めたリソース・ファイルの内容を解析します。代替実装("staticfortune"という名前)では、ビルド時にリソース・ファイルの内容を解析します。つまり、リソース・ファイルは実行可能ファイルに含まれなくなります。ファイルの解析に必要なコードはビルド時にのみ必要となるため、ネイティブ実行可能ファイルから省略されます。
- プロジェクト・ディレクトリに移動し、プロジェクトをビルドします:
cd ../staticfortune
mvn clean package
- トレース・エージェントを使用して、JVM (GraalVM JDK)でアプリケーションを実行します:
mvn -Pnative -Dagent exec:exec@java-agent
アプリケーションはランダムなメッセージを出力します。エージェントは、
target/native/agent-output
サブディレクトリに構成ファイルを生成します。 - 静的なネイティブ実行可能ファイルをビルドします:
mvn -Pnative -Dagent package
コマンドが完了すると、ネイティブ実行可能ファイル
staticfortune
がプロジェクトの/target
ディレクトリに生成され、使用できるようになります。 - デモを実行するには、ネイティブ実行可能ファイルを直接起動するか、Mavenプロファイルを使用して起動します:
./target/staticfortune
アプリケーションは、最初の実装とまったく同じように動作するはずです。
アプリケーションのpom.xmlファイルは、再度ネイティブ・イメージMavenプラグインを使用してネイティブ実行可能ファイルをビルドします。ただし、この実装では、ビルド時にクラス
demo.StaticFortune
を初期化するためのオプションが追加されています:-H:DashboardDump=staticfortune -H:+DashboardAll --initialize-at-build-time=demo.StaticFortune
JARファイルとネイティブ実行可能ファイルのサイズを比較します:
du -sh target/* 0B target/archive-tmp 76K target/classes 0B target/generated-sources 4.0K target/maven-archiver 4.0K target/maven-status 4.3M target/staticfortune 2.0M target/staticfortune-1.0-jar-with-dependencies.jar 32K target/staticfortune-1.0.jar 9.0M target/staticfortune.bgv 4.0K target/staticfortune.build_artifacts.txt 0B target/test-classes
ネイティブ実行可能ファイルのサイズが17MBから4.3MBに削減されました。
サイズが減少するのは、ネイティブ・イメージMavenプラグインで使用される
--initialize-at-build-time=
引数を使用したためです。 -
ビルドにより、staticfortune.bgvという名前のファイルが作成されました。これをGraalVMダッシュボードにロードして、
staticfortune
ネイティブ実行可能ファイルの構成を表示します。上のスクリーンショットは、
com.fasterxml
パッケージのコードが存在しなくなったことを示しています。また、java.util
、java.math
およびjava.text
パッケージに含まれるコードの量も削減されています。下のスクリーンショットは、文字列に指定されたヒープの量が大幅に削減され(767KBから184KB)、バイトも4MBから862KBに削減されたことを示しています。