原文はこちら。
The original entry was written by Oleg Šelajev (Developer advocate for GraalVM at Oracle Labs).
https://medium.com/graalvm/graalvm-quick-reference-b8d1dfe24241
GraalVMがJavaアプリケーションで役立つ方法には主として以下の3つがあります。
- 最先端のJITコンパイラを使用してJavaアプリケーションを高速化すること
- 迅速な起動と低メモリ消費のスタンドアロンネイティブ実行ファイルにコンパイルすること
- 他のサポート対象言語のライブラリやコードを使用してJavaアプリケーションを拡張すること
このクイックリファレンスはGraalVMで何ができるか、そして主要なオプションとコマンドを1ページに簡単にまとめて説明しているものです。
GraalVM Quick Reference 【PDF版】
https://www.graalvm.org/uploads/1p/graalvm-quick-reference_a4.pdf

ダウンロードして印刷いただけます。A4にきちんと収まりますので、オフィスに貼ったり、GraalVMでできること、オプションの使い方のリマインダーとして利用いただけます。印刷するのであればシャープに見えるPDF版をお使いください。USレターサイズのほうがお使いのプリンターの設定が楽な場合は、USレターサイズ版をお使いください。
GraalVM Quick Reference 【PDF版】
https://www.graalvm.org/uploads/1p/graalvm-quick-reference_a4.pdf
GraalVM Quick Reference 【USレターサイズ版】
https://www.graalvm.org/uploads/1p/graalvm-quick-reference_us-letter.pdf
このエントリではクイックリファレンスの情報を確認し、より詳細に説明します。
最初のパートでは、Javaアプリケーションの実行に焦点を当てています。何よりも、GraalVMディストリビューションには通常のJDK ツールがすべて含まれており、GraalVMをJDKとして使用できることを意味していることを覚えておくと良いでしょう。例えば、javac
ユーティリティを使ってJavaのソースコードをコンパイルできます。
javac MyApp.java
当然ながら、GraalVMを使ってJavaアプリケーションやその他のJVM言語を実行することもできます。Javaの実行に加え、GraalVMはその強力なJITコンパイラの恩恵を受け、他のJDKよりも高速に実行することが多々あるため、最先端のピークパフォーマンスに達します。
java -jar MyApp.jar
JavaアプリケーションをGraalVMでジャストインタイムで実行する場合、基礎となるJVMは通常のJava HotSpotTM VMです。これは構成オプションのほとんどが同じであることを意味します。例えばアプリケーションのクラスパスを指定する場合、以下のように記述します。
java -cp target/myapp.jar com.example.Main
GraalVMコンパイラは通常ネイティブ共有ライブラリに事前コンパイル済みのモード、つまりlibgraal
として実行されます。
Compiler Operating Modes
https://www.graalvm.org/reference-manual/compiler/#compiler-operating-modes
しかしながら、コンパイラのコードはJavaで記述されており、JARファイルとして利用することもできます(jargraal
)。そのため、わずかにパフォーマンスのプロファイルに違いがあります。jargraal
の場合、コンパイルにヒープメモリを使う結果ウォームアップに時間がかかる(例えば、コンパイラのJavaコードをコンパイルする)というものです。以下のオプションで利用モードを構成できます(デフォルトで+が有効化、つまりlibgraalが有効になっています)。
-XX:+-UseJVMCINativeLibrary
コンパイラをJARやネイティブライブラリとして実行することに加えて、最適化設定を指定できます。具体的には、ウォームアップを高速化するためにeconomy
を選択したり、enterprise
を使用して最高のピークパフォーマンスを得ることができます(enterprise
を利用する場合はもちろんGraalVM Enterpriseが必要です)。
Compiler Configuration on JVM
https://www.graalvm.org/reference-manual/jvm/Options/
-Dgraal.CompilerConfiguration=enterprise|community|economy
JITコンパイラの影響はアプリケーションの劇的なスピードアップにつながることがありますが、時としてどのコンパイラが機能しているのか、アプリケーションコードが実際にtop tierに達しているかどうか、どのメソッドがコンパイラに到達しているか、がわからないことがあります。
-Dgraal.PrintCompilation=true
ログを見るだけでなく、デバッグ出力を有効化できます。例えば、コンパイラのグラフを出力して解析し、さらなる最適化の機会を見つけることができます。
-Dgraal.Dump=:2
そしてもちろん、JVMの他の機能もGraalVMで動作します。例えば、コードのインストルメント、実行時のクラス生成、その他のJavaの「エージェント」のアタッチが可能で、Javaベースのエージェントとネイティブエージェントの両方が動作します。注目すべき例としては、ネイティブイメージのビルドを簡素化するための設定アシストエージェントがあります。
-javaagent:path/to/jar.jar
-agentlib:path/to/native/agent
GraalVMを使用する2つ目の大きな利点は、Native Image機能、つまりアプリケーションをAOT(ahead of time)コンパイルしてネイティブバイナリにする機能です。これを使用するには、native-image
コンポーネントをインストールする必要があります。
Native Image
https://www.graalvm.org/reference-manual/native-image/
Native Imageを有効化するには、GraalVMディストリビューション用のコンポーネントのJARファイルをダウンロードし、以下のように実行します。
gu install -L native-image.jar
この後、インストール済みのnative-imageユーティリティを使ってアプリケーションをネイティブバイナリにできます。
native-image [options] MyClass
あるいは、javaコマンドに似たjarファイルの構文を使用することもできます。
native-image -jar MyApp.jar
生成された
バイナリを実行可能ファイルのように実行してください。
./myApp
実行ファイルの代わりに共有ライブラリをビルドしたい場合は、--shared
オプションを指定してください。
Create a Shared Library
https://www.graalvm.org/reference-manual/native-image/ImplementingNativeMethodsInJavaWithSVM/#create-a-shared-library
公開するメソッドを @CEntryPoint
アノテーションでマークする必要がありますが、このトピックの詳細はこの記事の範囲を超えています。
--shared
もう一つの非常に便利と思われるのは、 libc
のようなOSライブラリが実行ファイルにリンクされている静的にリンクされたバイナリのビルドです。
Static Native Images
https://www.graalvm.org/reference-manual/native-image/StaticImages/
利用するlibc
実装を選択することも可能です。glibc
をデフォルトで使用し、muslc
も選択できますが、muslc
を選択する場合は、ビルド環境を少し準備する必要があります。
--static --libc=muslc
JavaScript、Ruby、Python、R などのTruffleベースの言語を動かすためのインフラを含めることが可能です。これには言語のインタプリタ、Truffleフレームワーク、および JITコンパイラが含まれているため、コードを実行時にコンパイルして高速に実行できます。
Truffle Language Implementation Framework
https://www.graalvm.org/graalvm-as-a-platform/language-implementation-framework/
例えば、それぞれに対応する言語のサポートが含まれます。
--language:js
--language:python
--language:llvm
--language:ruby
--language:js
もう一つの魅力的な機能は、ネイティブイメージ実行可能ファイルに対するprofile-guided optimizations(プロファイルガイド付き最適化)です(訳注:この機能はGraalVM EEでのみ利用可能)。
Profile-Guided Optimizations
https://www.graalvm.org/reference-manual/native-image/PGO/
インストルメント対象のバイナリを生成し、それに関連するワークロードを適用し、JITコンパイラが行うように実行されたコードのプロファイルを記録し、それらのプロファイルを使用して本番のバイナリをビルドできます。
native-image — pgo-instrument MyApp
./myApp
native-image — pgo profile.iprof MyApp
また、ネイティブイメージのビルドプロセスで起こっていることをより詳しく知りたい場合、例えばクラスが初期化されたクラスチェーンを理解したい場合には、便利なオプションを選択して使用できます。
特定のクラスへの初期化パスをトレースするには、以下のようにします。
-H:+TraceClassInitialization=package.class.Name
ネイティブイメージのビルドはJavaプロセスなので、ブレークポイントをコードに配置して何が起こっているのか完全に把握できます。
--debug-attach=[port]
これらの他にも、ネイティブイメージのビルドやランタイムの動作を設定するための便利なオプションがたくさんあります。これらについては後ほど説明しますが、エキスパートヘルプオプション(expert help option)を使えば、何が利用できるかの概要を知ることができます。
--expert-options-all
GraalVMを使用する3つ目の大きな利点は、polyglot runtimeです。これは複数の言語を実行できる機能で、JavaScript用GraalVMエンジンを搭載したNode.jsプラットフォームが含まれています。
Polyglot Programming
https://www.graalvm.org/reference-manual/polyglot-programming/
そのため、nodeアプリケーションがあれば、以下のようにnode
コマンドを呼び出すことで実行できます。
node myApp.js
その上、サポート対象言語で記述されたプログラムを実行するために利用可能な言語ランチャーが多数用意されています。
js myApp.js
graalpython myApp.py
ruby myApp.rb
R myApp.r
lli myApp
nodeを含むランチャーはデフォルトでネイティブモードで動作し、インタプリタはネイティブイメージのバイナリとしてコンパイルされます。そのため、Javaクラスを使用するためにJVMとの相互運用性を有効にするには、--jvm
オプションを使用し、他の言語の場合は--polyglot
を使用します。
--polyglot --jvm
言語エンジンには、リソースの量を制限するための機能がいくつかあります。
Configure Sandbox Resource Limits
https://docs.oracle.com/en/graalvm/enterprise/20/docs/reference-manual/embed-languages/sandbox/
例えば、言語コンテキストが実行できる時間をミリ秒単位で指定できます。
--sandbox.MaxCPUTime=Nms
大事なことを言い忘れていましたが、GraalVMの言語では、一般的な開発者向けのツールをすぐに利用できるようにサポートしています。
GraalVM Debugging and Monitoring Tools
https://www.graalvm.org/docs/tools/
言語のセマンティクスを修正する言語インタープリタを実装し、強力な仮想マシン、GCアルゴリズムの選択、デバッガ、プロファイラ、メモリアナライザ、その他のツールを無料で手に入れることができるというのは、GraalVMエコシステム全体の中で最もエキサイティングな部分の一つです。
以下のオプションを指定して、Chrome DevTools デバッガをベースにしたデバッガ、サンプリングプロファイラ、トレースプロファイラ、メモリアナライザをそれぞれ有効にします。
--inspect
--cpusampler
--cputracer
--memsampler
Conclusion
GraalVMは、Java、JVM言語、JavaScript、Ruby、Python、Rなどのアプリケーションに使用できる多くの機能を提供する汎用性の高いプロジェクトです。
より優れたJITコンパイラを使用することに始まり、アプリケーションのネイティブ実行ファイルのビルド、異なる言語でのコンポーネントの実行まで、GraalVMは今すぐにでも使用できます。
このクイックリファレンスで、最もよく使われるオプションを概説し、GraalVMの様々な機能を紹介しました。
是非クイックリファレンスをダウンロードして印刷いただき、壁に貼ってください。たとえ現在GraalVMの提供する機能のほんの一部しか使用していないとしても、GraalVMプロジェクトがいかに興味深いものであるかを思い出させる役に立つのであればうれしく思います。
GraalVM Quick Reference 【PDF版】
https://www.graalvm.org/uploads/1p/graalvm-quick-reference_a4.pdf
そのついでに、GraalVMディストリビューションをダウンロードして、例えばJavaアプリケーションをより高速に実行してみたり、ネイティブイメージを使ってマイクロサービスをよりクラウドに適した形にしたり、他の言語のライブラリを使ってアプリケーションを機能強化してみたり、といったような、このクイックリファレンスに記載の内容を試してみてください。
GraalVM Downloads
https://www.graalvm.org/downloads/