Image化が話題に挙がりました。Imageってよく聞くけどあまり知らないなぁ...」と思い色々と調べてみたのでまとめます。この記事ではGraalVMの中核技術の概要を把握し、簡単にその機能を使ってみることをゴールとします。読む上で以下のようなことを前提知識として進めます。(つまるところ、私自身のレベル感です)GraalVMという名前は聞いたことがあるJavaもしくはその他のJVM言語を使ってプログラムを書いたことがあるJVMやコンパイラに関するふんわりとした理解JITコンパイル、AOTコンパイルと聞いてなんとなくどういったものかイメージがつくJVMのC1、C2と聞いてなんとなくどういったものかイメージがつくGraalVMとはGraalVMはユニバーサルなVMで、JVM言語はもちろんのことJavaScript、Pythonなど動的言語、LLVM-basedなネイティブコード等の様々な言語を実行できます。GraalVMは大きく以下2つの特徴を持っています。PolyglotNativePolyglotWeblioの訳では「数か国語に通じている人」と説明されています。訳の通りGraalVMは多言語対応されており、JVM言語以外の言語の実行環境としても動作します。JavaからJavaScriptのAPIを呼び出すなど、多言語を混ぜたコードの記述が可能で、各言語のエコシステムを活かしたコーディングが可能になります。Imageと呼ばれるスタンドアローンで実行可能な形にコンパイルすることができます。Imageに関して詳しくは後述します。GraalVMの中核技術GraalVMはJVMの機能を包括しており、JVMのできることは基本的にすべて行えます。HotSpotVMをベースに作られています。JVMのとは違ったGraalVMにおける中核の技術として以下の3つが挙げられます。ImageGraalGraalはGraalVMのにおけるJITコンパイルラです。Interfae)を利用してC2コンパイラを置き換えます。243で定義されるJavaで、JITコンパイラを記述する際のインタフェースです。InterfaceはC++で実装されていますが、GraalVMでのGraalやJVMCIはJavaでの実装がされています。GraalVMGraalとGraalVMは別物で、GraalVMというとJVMの機能を包括したVMを指し、GraalはJITコンパイラの事を指します。GraalはJava10以降のOpenJDKからの利用も可能です。317)TruffleTruffleは言語実装フレームワークで、GraalVM上でJVM以外の言語が動作する際に使われる仕組みです。このフレームワークを利用することにより、GraalVMはPolyglotなVMとして、さまざまな言語を動作させることができると同時に、独自の言語を実装することも可能です。Image化を行なうことができます。Imageは以下のようなものを含みます。Image化を行なうと以下のような特徴を得ることができます。クラスローダなどのオーバヘッドがなくなり、起動が早くなるJVM言語のメモリフットプリントを削減することができる上記のような特徴からコンテナ化やサーバレスアーキテクチャでの利用の際にメリットがあると思われます。ここで、注意すべきなのは、JITコンパイルではなくAOTコンパイルを行なうことにより、JITコンパイルの特徴(ホットスポットなコンパイル、OSの差異を吸収してくれる等)はなくなるということです。リフレクションやダイナミックプロキシなどを行なう場合は、対象クラスを追加で設定するなど追加の作業が必要なようです。Image化のサポートがされるようです。WorldGraalVMの概要についてまとめたところで、実際に使ってみたいと思います。Worldとして以下のことをやってみたいと思います。Worldを実行する環境を以下にまとめます。LTS)GraalVM(19.3.1)GraalVMのインストールまずはGraalVMをインストールします。PATH=/usr/lib/graal-vm/graalvm-ce-java11-19.3.1/bin:$PATH以上で、インストールは完了です。インストールするディレクトリはどこでも良いですが。今回は/usr/libとしました。Javaのバージョンを確認してみます。sharing)GraalVMをインストールすると、通常のJavaコマンドとは別に以下のコマンドが利用可能になります。Worldのコードを動かしてみたいと思います。HelloWorld.javaを作成し以下のソースコードを記述します。}}コンパイルと実行は通常のJavaと同様にjavac、javaコマンドで行います。APIを利用することで可能となります。JavaからJavaScriptを呼び出すコードを以下のように記述します。}}org.graalvm.polyglot.Contextクラスはゲスト言語に対する、実行環境を提供します。実際のコードの実行はevalメソッドを利用します。引数に言語のIDを第二引数に実際のコードを記述します。evalの実行結果をorg.graalvm.polyglot.Valueクラスで受け取ることにより、引数ありの関数としても定義することもできます。コンパイルと実行は通常のJavaと同様にjavac、javaコマンドで行います。Ployglot!このようにして、GraalVMではPolyglotなコードの記述が可能となります。Image化を試して見たいと思います。Image化にnative-imageコマンドを利用できます。native-imageコマンドのインストールはguを利用できます。native-imageコマンドを利用するためには以下の3つが事前にインストールされている必要があります。glibc-develzlib-develgcc以下のコマンドで、native-imageコマンドをインストールします。Worldコードをネイティブイメージ化し、その実効速度の差を見てみます。0m0.000s実行タイミングや環境にもよりますが、プログラムの実行速度を表すuserを比較すると30~100倍ほど早く実行されます。Image化を行って早くなるのはあくまで起動速度みたいなので、デーモンのような常駐するプロセスでは恩恵が薄れていくと思われます。Image化したいと思います。Image化を行なうと実行時に以下のようなエラーが吐かれます。HelloPolyglot.main(HelloPolyglot.java:6)これは、通常のコンパイルではJavaScriptエンジンがImageの中に含まれないからです。エラーメッセージにかかれている通り--language:jsフラグを指定して再度コンパイルしてみます。Ployglot今度は実行できました。終わりに(感想)GraalVMについて調べて、少しだけその機能を試してみました。前述しましたが、Truffleを使えば俺々言語みたいなのも実装できそうですし、理解が深まればまだまだ面白そうな点があるように感じました。GraalVMで検索すればより質の高い記事や資料が日本語でたくさん見つかるので、より詳しくはそちらを参照してください。reserved.引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。