こんにちは id:dhigashi です。最後にブログを書いてから半年が経っていました。こんにちは令和
Oracle Functions (Limited Availability)を触ってみる - Cloudii blog
以前 Misreading Chat で GraalVM (Graal/Truffle) について知ってから、ふーんと思いつつ触っていなかったのですが、
Oracle Cloud 上で GraalVM EE を利用できるし Oracle Cloud に Always Free もきて実質無料で EE 版が利用できる?ということで試してみます。
(Oracle Cloud 関係なく EE 版は検証用に無料で利用できます。勿論 CE 版は無料で実環境でも利用できます。)
GraalVM Enterprise is free to use (including support) on Oracle Cloud. https://www.oracle.com/a/ocom/docs/tools/graalvm-ee-faq.pdf
目次
- 目次
- GraalVM
- GraalVM の導入
- GraalVM HotSpot での実行
- Java から JavaScript を評価
- Native Imageプラグインの導入
- Native Image の作成
- まとめ & 次に
GraalVM
GraalVM とは公式サイトから引用すると High-performance polyglot VM です。
JVM 言語 (Java, Scala, Kotlinなど) だけでなく JavaScript, Python, Ruby などの言語を実行でき、複数の言語を組み合わせて実行する事もできます。
他には、Native Image という実行可能なファイルを事前コンパイル (AOT) で作成することができます。
こちらは、Java VMと比較して起動時間の短縮、メモリのフットプリントが低くなる効果などが期待できます。
GraalVM の導入
こちらのドキュメントに従い OCI 上にインスタンスを作成し GraalVM をインストールします。
執筆時の GraalVM EE のバージョンは 19.2.0.1
です。
Oracle GraalVM Downloads から Oracle GraalVM Enterprise Edition Core を取得しインスタンスに配置し PATH を設定します。
# ~/.bashrc GRAALVM_VERSION=ee-19.2.0.1 export GRAALVM_HOME=graalvm-$GRAALVM_VERSION export JAVA_HOME=$GRAALVM_HOME export PATH=$GRAALVM_HOME/bin:$PATH
java の version を確認すると Java HotSpot(TM) 64-Bit GraalVM EE 19.2.0.1
となっていますね。
$ java -version java version "1.8.0_221" Java(TM) SE Runtime Environment (build 1.8.0_221-b11) Java HotSpot(TM) 64-Bit GraalVM EE 19.2.0.1 (build 25.221-b11-jvmci-19.2-b02, mixed mode)
GraalVM HotSpot での実行
とりあえず HelloWorld
public class HelloWorld { public static void main(String args[]){ System.out.println("Hello, World"); } }
OpenJDK等 と変わらず実行できますね。
$ javac HelloWorld.java
$ ls
HelloWorld.class HelloWorld.java
$ java HelloWorld
Hello, World
Java から JavaScript を評価
Java から JavaScript を評価する Polyglot なコードも書いてみます。
import java.io.File; import org.graalvm.polyglot.*; import org.graalvm.polyglot.proxy.*; public class HelloWorld { public static void main(String args[]) throws Exception { Context polyglot = Context.create(); polyglot.getBindings("js").putMember("args", ProxyArray.fromArray((Object[])args)); Source source = Source.newBuilder("js", new File("sample.js")).build(); Value value = polyglot.eval(source); System.out.println(value.asString()); } }
呼び出されている js はこちら
if (args.length == 0) { 'Hello, world'; } else { 'Hello, ' + args[0]; }
実行できますね。
$ javac HelloWorld.java $ java HelloWorld Daisuke Hello, Daisuke
Native Imageプラグインの導入
続いて Native Image を作成してみましょう。
Oracle GraalVM Downloads から Oracle GraalVM Enterprise Edition Native Image Early Adopter を取得し GraalVM Updater ツールを用いてインストールします。
$ gu -L install ./native-image-installable-svm-svmee-linux-amd64-19.2.0.1.jar $ native-image --version GraalVM Version 19.2.0.1 EE
Native Image の作成
先程コンパイルした HelloWorld の Native Image を作成します。
めっちゃ時間がかかります。
$ native-image --language:js HelloWorld Build on Server(pid: 25730, port: 36937) [helloworld:25730] classlist: 3,309.02 ms [helloworld:25730] (cap): 1,910.67 ms [helloworld:25730] setup: 5,775.61 ms [helloworld:25730] (typeflow): 99,869.74 ms [helloworld:25730] (objects): 40,267.83 ms [helloworld:25730] (features): 9,799.05 ms [helloworld:25730] analysis: 153,370.18 ms [helloworld:25730] (clinit): 1,528.93 ms 8853 method(s) included for runtime compilation [helloworld:25730] universe: 6,454.63 ms [helloworld:25730] (parse): 23,207.82 ms [helloworld:25730] (inline): 35,147.33 ms [helloworld:25730] (compile): 303,466.29 ms [helloworld:25730] compile: 369,574.51 ms [helloworld:25730] image: 18,833.84 ms [helloworld:25730] write: 1,619.59 ms [helloworld:25730] [total]: 561,538.66 ms
バイナリが作成され実行することができました。
$ ls
HelloWorld.class HelloWorld.java helloworld sample.js
$ ./helloworld Daisukeee
Hello, Daisukeee
GraalVM HotSpot と GraalVM Native Image の実行時間を比べると、大きく差があります。
アプリケーション部分では差は出ないと思いますので、JVM の起動時間の分早くなっているのでしょう。
$ time java HelloWorld Daisuke Hello, Daisuke real 0m1.177s user 0m1.891s sys 0m0.098s $ time ./helloworld Daisukeee Hello, Daisukeee real 0m0.005s user 0m0.003s sys 0m0.003s
まとめ & 次に
GraalVM を用いて、複数の言語を同時に実行する、Native Image で実行可能なバイナリを作成・実行を行いました。
GraalVM に含まれる JIT コンパイラの Graal は C1, C2 を置き換えるもので、同等以上のパフォーマンスを発揮するものかは試していないので、GraalVM がそのまま今までの JDK を置き換えるものかは分かりませんが、とても面白いですね。
特に Native Image は、簡単な CLI ツールなどはワンバイナリで配布できるといった理由で Golang 等で作成する事があるあるだったと思うのですが、JVM 言語 (それ以外も) + Native Image も候補に入れられるのではないでしょうか。
また、サーバーレスアーキテクチャでは JVM 言語で実装した場合、JVM の起動時間、メモリのフットプリントなどによって不利になる場合がありました。
次回は Oracle Cloud のサーバーレスサービスである Oracle Functions で Native Image を用いてパフォーマンスを改善できるか見ていきたいと思います。
(その2 に続きます)