Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Guide to GraalVM (JJUG CCC 2019 Fall)

2,856 views

Published on

2019/11/23 JJUG CCC 2019 Fall
「多言語対応の仮想マシンGraalVMが照らす未来」のセッションスライドです。
---
オラクル社からGraalVMというOSSプロダクトが発表され、話題を呼んでいます。GraalVMは、Javaで書かれたJITコンパイラ、Graalを搭載しています。さらに、言語実装用のフレームワークTruffleを提供しており、そのフレームワークを使って実装したJavaScriptやRuby、Pythonなど他の言語を、GraalVMは高いパフォーマンス実行できます。GraalVMを多言語対応の仮想マシンと呼ぶ理由です。加えて、それらすべての言語間で、相互に呼び出しができます。また、ネイティブイメージを作成し、JVMを利用せずにアプリケーションを実行できます。MicronautやQuarkus、Helidonといった最新のフレームワークが、この機能を利用して起動時間の短縮を図っています。ともすれば、GraalVMとは、ネイティブイメージを作成するためのものである、というイメージを持たれている方もいるかもしれません。しかし、GraalVMが持つパワーは、それだけではありません。このセッションでは、上述のGraalVMの概要の説明やデモに加え、単にGraalVMの使い方に留まらず、GraalVMによって今後何が実現されるのか、世界でのGraalVMの活用事例、Java on iOSとの関連、といったことお話しします。

Published in: Technology
  • Be the first to comment

Guide to GraalVM (JJUG CCC 2019 Fall)

  1. 1. 2019年11月25日 阪田 浩一 / ヤフー株式会社 多言語対応の仮想マシン GraalVMが照らす未来 #ccc_i6
  2. 2. 自己紹介 2 • 阪田 浩一 (@jyukutyo) • ヤフー株式会社 大阪拠点所属 • 第9代黒帯〜プログラミング言語(Java)〜 • JVMがとてつもなく好き • 関西Javaエンジニアの会 代表&創設者
  3. 3. このセッションの役割 3 GraalVMに 初めて触れる人へ、 概要を日本語で 説明すること
  4. 4. Oracle Code OneにおけるGraalVM 4 • セッション数が激増 • 2017: 4 • 2019: 37 • 内容はさまざま (機能については後述) • GraalVMそのもの • フレームワークでのネイティブイメージ活用 • Polyglot関連
  5. 5. もしも、 あらゆる言語を 実行できるVMが あれば… 5
  6. 6. あの処理、 あっちの言語の ライブラリを使えば すぐにできるのに… 6
  7. 7. そんな願いを実現する (可能性を秘めた) VMが、 GraalVM 7
  8. 8. GraalVMを一言で言うと 8 ユニバーサルVM
  9. 9. ここでのユニバーサルとは 9 あらゆる言語の 実行環境となれる 能力と機能が あること
  10. 10. GraalVMについての誤解 10 ❌ Javaの ネイティブイメージを 生成するためのツール
  11. 11. 従来のJVMで実行できる言語 11 • Java • JVM用に新たに作成したもの • Scala, Kotlin, Groovyなど • 他言語をJVM上に実装したもの • JRubyなど • など多数
  12. 12. 現在GraalVMで実行できる言語 12 • JVMで実行できる言語すべて • JavaScript • Ruby • Python • R
  13. 13. GraalVMの構造 13 JVM (HotSpot VM) + α
  14. 14. + α 機能の1つ 14 • Truffle: 言語実装用のライブラリ • このライブラリを用いて実装した言語は、 すべてGraalVM上で実行できる • トラフル (英)、トリュフ (仏)
  15. 15. Truffleで実装した言語 15 • GraalJS (JavaScript) • ECMAScript 2019 仕様互換、Node.js v12.10.0 • TruffleRuby (Ruby, Experimental) • Ruby 2.6.2 ベ ー ス • GraalPython (Python , Experimental) • Python3.7 互換 • FastR (R , Experimental) • GNU R 3.6.1 互換
  16. 16. デモ 16 GraalVMで JavaScriptを実行
  17. 17. セットアップ 17 https://www.graalvm.org/
  18. 18. GraalVMの2つのエディション 18 • Community Edition (CE) • OSS (クラスパス例外付き GPL v2) • https://github.com/oracle/graal • Enterprise Edition (EE) • ライセンス契約が必要 (評価は無償) • CEよりパフォーマンスがよい • CEよりセキュリティを強化している
  19. 19. Oracle Labsが 開発 19
  20. 20. デモ 20 GraalVMで JavaScriptを実行
  21. 21. (なお、Java 11で Nashornは非推奨に なりました) 21
  22. 22. 単に各言語を 実行できるだけでは ない 22
  23. 23. パフォーマンスを大幅に 低下させることなく、 言語間で 相互呼び出しができる 23
  24. 24. デモ 24 JavaScriptから Javaを呼び出す
  25. 25. GraalVMのビジョン 25 パフォーマンスを 犠牲にせず、 言語間の抽象化をする
  26. 26. GraalVMとは 26 さまざまな言語を 実行できる (polyglot)、 ユニバーサルVM
  27. 27. 開発ツールの サポートもある 27
  28. 28. Google Chrome DevToolsでのデバッグ 28
  29. 29. Graal VisualVM 29
  30. 30. デモ 30 Chrome DevTools でのデバッグ
  31. 31. GraalVMとHotSpot VMの違い 31 HotSpot VM Compiler Interface C2C1 HotSpot VM C++ GraalVM Compiler Interface GraalVM JITコンパイラC1 HotSpot VM JVMCI Java
  32. 32. GraalVM JITコンパイラ 32 • JVMCI (JVM Compiler Interface) を用いて 作成した新JITコンパイラ • 以前は単にGraalと言われていた • Javaで書かれている
  33. 33. ベンチマーク 33 最新のベンチマーク結果は、右下のURL からご確認ください https://renaissance.dev/
  34. 34. アロケーションの多い アプリケーションには、 GraalVM JITコンパイラが 有効 34
  35. 35. たとえば リアクティブストリーム で構築したものや 35
  36. 36. Scalaなど 関数型プログラミング モデルで構築したもの 36
  37. 37. Twitter社の事例 37 • OpenJDKベースの独自JDKに、GraalVM JITコ ンパイラをバックポート • 2年前2017年には、すでに本番環境で活用 • 数千台のサーバ、Scalaアプリケーション • サーバリソースを削減し、台数削減 • 大きなコスト削減になった
  38. 38. GraalVM JITコンパイラ 38 • Truffleで実装した言語は、 GraalVM JITコンパイラでの動作を 前提とする
  39. 39. GraalVMで動作する言語 39 HotSpot VM JVMCI GraalVM JITコンパイラ JVM⾔語 Truffle LLVMJS R Python C C++ Fortran Ruby Java, Kotlin, Scala, JRubyなど
  40. 40. 言語実装のしくみ 40 対象言語のASTの インタプリタを、 Truffle APIを用いて Javaで実装する
  41. 41. 対象コードのASTと インタプリタの両方を 評価することで 高性能のコードを 生成できる 41
  42. 42. ゴールドマン・サックス社の事例 42 • 1990年代初め、独自に言語を開発 • 現在までコードが増え続ける • 言語自体の運用開発が課題に
  43. 43. ゴールドマン・サックス社の事例 43 • その言語をTruffleベースに移行 • 他言語との相互呼び出しが可能に • 言語実装のメンテナンス性が向上した • 実行パフォーマンスが向上した • 事例発表動画 • Oracle Code One 2018: https://www.youtube.com/watch?v=MUECwHdr07Q
  44. 44. 究極的には 44 自分で実装した プログラミング言語を GraalVMで実行できる
  45. 45. 言語実装サンプル 45 • GraalVMのリポジトリ内 • SimpleLanguage • https://github.com/graalvm/simplelanguage • Simpleとあるけれど、簡単ではない
  46. 46. 私もやってみました 46 • https://github.com/jyukutyo/JVM-Math-Language • Devoxx US 2017で、Olegさんのセッションを 聴いたことが、すべてのきっかけ!! • How to create a new JVM language by Oleg Šelajev • https://www.youtube.com/watch?v=8Lt8au76emA
  47. 47. ここまでの内容 47 • GraalVM • GraalVM JITコンパイラ • Truffle: 言語実装用ライブラリ • パフォーマンスを犠牲にせず 言語間の抽象化をする
  48. 48. ネイティブイメージの 話題なし 48
  49. 49. GraalVMのネイティブイメージ生成 49 • ネイティブイメージ (実行可能なバイナリ) を生成する機能 • 生成したイメージ (ファイル) をそのまま 実行する • つまり、起動にJVM (JDK/JRE) が不要
  50. 50. この機能と、 今までの機能に 何の関連が?? 50
  51. 51. 答えは、 Oracle Database 51
  52. 52. Oracle Database 52 • ユーザ定義関数をJavaで作成できる しかし、 • GraalVMの機能を組み込めば、Javaは もちろん、他言語も使える • 更新は、GraalVM側に任せられる
  53. 53. Oracle Databaseに GraalVMを組み込む 53
  54. 54. Oracle Databaseへ組み込むには 54 • JVMが課題 • サイズが大きい • 初期化処理が長い • メモリ使用量が大きい • そのままでは、データベースでの 利用はできない
  55. 55. GraalVM自体を ネイティブイメージに する! 55
  56. 56. ネイティブイメージにすると 56 • JVMが不要 • サイズが小さく済む • 起動時間が短くなる • メモリ使用量が少なくなる • ただし、同じプラットフォームでしか 動作しない
  57. 57. Oracle Database MLE 57 • MLE: Multilingal Engine • https://www.oracle.com/technetwork/database/multilingual- engine/overview/index.html • MySQLでもMLE Pluginを開発中 select validator.isEmail('alice@example.com’) from dual;
  58. 58. こうした経緯で開発した ネイティブイメージ 生成機能が GraalVMの機能の1つ となった 58
  59. 59. デモ 59 ネイティブイメージ 生成
  60. 60. ネイティブイメージのメリットまとめ 60 • 起動時間が短くなる • メモリ使用量が少なくなる • サイズが小さくなる
  61. 61. ネイティブイメージには さらなる可能性も… 61
  62. 62. Java on iOS 62
  63. 63. JVMが不要であるため、 ネイティブイメージは iOS上で実行できる 63
  64. 64. (AppleはiOS上で JVMを動作させることを 禁じている) 64
  65. 65. Java on iOS 65 • A plan to bring Java to iOS | InfoWorld • https://www.infoworld.com/article/3407781/a-plan-to-bring-java- to-ios.html • Java on iOS, for real. – Gluon • https://gluonhq.com/java-on-ios-for-real/ • rebooting OpenJDK mobile • https://mail.openjdk.java.net/pipermail/mobile-dev/2019- June/000584.html
  66. 66. どんなアプリケーション でも、 ネイティブイメージに する方がよいのか? 66
  67. 67. JITコンパイル (JVM) と AOTコンパイル (GraalVM) 67
  68. 68. https://twitter.com/thomaswue/status/1145603781108928513
  69. 69. ネイティブイメージが適切なケース 69 • FaaS • 起動してすぐに終了する • クラウドで実行する 大規模アプリケーション • リソースを節約し、コストを削減する • 頻繁にリリース(再起動)する アプリケーション • ≒ マイクロサービス
  70. 70. ネイティブイメージ対応フレームワーク 70 • Micronaut https://micronaut.io/ • Quarkus https://quarkus.io/ • Helidon https://helidon.io/ • Spring Framework (Boot)も対応作業中 (現在はExperimental) • https://github.com/spring-projects/spring-framework/wiki/GraalVM-native-image- support
  71. 71. デモ 71 Quarkusの起動 (JVM, ネイティブイメージ)
  72. 72. ネイティブイメージ機能 の詳細 72
  73. 73. + α 機能の1つ 73 • Substrate VM • ネイティブイメージの生成ツール、実行VM • 実行時、GCやスレッドのスケジューリング、 コードのキャッシュなどを実施 • 単にVMであって、JVMではない
  74. 74. ネイティブイメージ生成プロセス 74 アプリケーション ライブラリ JDK Substrate VM 下記の繰り返し: 解析ポイント ↓ 初期化処理実⾏ ↓ ヒープのスナップショット⽣成 ELFファイル コード (textセクション) イメージヒープ (dataセクション)
  75. 75. 生成時に 初期化処理を実行し、 起動時間を 短縮する 75
  76. 76. 生成において、 混乱しやすい部分を いくつか紹介します 76
  77. 77. 生成時の初期化 77 import java.util.Date; class InitializedDate { static final Date INITIALIZED_DATE = new Date(); } class InitializeSample { public static void main(String[] args) { System.out.println("INITIALIZED_DATE: " + InitializedDate.INITIALIZED_DATE); System.out.println("main: " + new Date()); } } 2つの日付は、異なる??
  78. 78. 初期化タイミング 78 • アプリケーションのクラスは、 すべて実行時に初期化 • それ以外のクラスは、生成時初期化 • --initialize-at-build-time=[クラス名] • 生成時に初期化 • --initialize-at-run-time=[クラス名] • 実行時に初期化
  79. 79. 生成時初期化を指定すると… 79 import java.util.Date; class InitializedDate { static final Date INITIALIZED_DATE = new Date(); } class InitializeSample { public static void main(String[] args) { System.out.println("INITIALIZED_DATE: " + InitializedDate.INITIALIZED_DATE); System.out.println("main: " + new Date()); } } $ ./initializesample INITIALIZED_DATE: Wed Oct 23 15:05:19 JST 2019 main: Wed Oct 23 15:08:07 JST 2019
  80. 80. リフレクションやJNIのサポート 80 • 現在は利用可能に 1. 生成時の静的解析 • Class.getMethod(String, Class[]) など 2. 設定ファイルに明示的に記述 • 参考: Tracing Agent
  81. 81. リフレクション利用設定 81 [ { "name" : "java.lang.String", "fields" : [ { "name" : "value", "allowWrite" : true } ], "methods" : [ { "name" : "format", "parameterTypes" : ["java.lang.String", "java.lang.Object[]"] } ] } ]
  82. 82. ライブラリでの対応 82 • 設定ファイルを META-INF/native-imageに配置 • 生成時に自動的に読み込まれる
  83. 83. ネイティブイメージの現状 83 • Experimental • サポートプラットフォーム • x86 64ビットシステム • LinuxまたはmacOS
  84. 84. GraalVMのリリースロードマップ 84 • 3ヶ月ごと、年4回のリリース • 2019/11 – GraalVM 19.3 • 2020/02 – 20.0 • 2020/05 – 20.1 • 2020/08 – 20.2 • 2020/11 – 20.3
  85. 85. 2日前にリリースされた 19.3にて、 Java 11に対応! (8,11の2つを出している) 85
  86. 86. GraalVMのリリースロードマップ 86 • 年間最後のリリースは、LTS • 2019/11 – 19.3 • 2020/11 – 20.3 • 次の1年間、アップデートを提供 • 19.3は、2020年末まで • 20.3は、2021年末まで • CEのケースであり、EEは別となる
  87. 87. OpenJDKとは別の、 独立した開発 87
  88. 88. AOTでも JITと同じくらいの ピーク時パフォーマンス が今後の目標、 とのこと 88
  89. 89. まとめ GraalVMとは 89 • Javaの未来に関わる、キープロダクトの1つ! • GraalVM JITコンパイラ • Truffle • 言語実装用ライブラリ • SubstrateVM • ネイティブイメージ用ツール
  90. 90. GraalVMの2つのモード 90 • JITモード • JVMとGraalVM JITコンパイラで アプリケーションを実行 • AOTモード • ネイティブイメージを生成し、JVMなしで アプリケーションを実行 • どちらのモードのことなのか、意識する
  91. 91. GraalVMのサンプル事例 91 • GraalVM JITコンパイラ単体で、 ピーク時のパフォーマンスを向上させる • Truffleで、複数言語を活用した アプリケーションを構築 • SubstrateVMで、ネイティブイメージを 生成し、起動時間短縮とリソース消費削減

×