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.

Getting Started GraalVM (再アップロード)

34 views

Published on

Getting Started GraalVM
見えないスライドがあるので、再アップロードしました。

Published in: Technology
  • Be the first to comment

Getting Started GraalVM (再アップロード)

  1. 1. GraalVM超入門 / Getting Started GraalVM 2018/12/15 JJUG CCC 2018 Fall #ccc_c2 @tamtam180
  2. 2. テーマ 2 Polyglot/Truffle 多言語Mix Graal/GraalVM Native Image おまけ
  3. 3. 前提 • 初心者向けの内容です • 少しでもGraalで遊んだことがある人に は、 何も得るものはありません 3
  4. 4. アジェンダ • 自己紹介 • GraalVMとは –用語の説明/おさらい含む • Polyglotサンプル • JavaプログラムをNative Imageに変換 する • こぼれ話(サンプル集) 4
  5. 5. 自己紹介
  6. 6. 自己紹介 • Name: Kiyotaka Suzuki • Twitter: @tamtam180 • Main works – SquareEnix (約5.5年) • PlayOnline, FF-XIV, etc. – SmartNews (約5年) • Cross-functional Expert Team • Senior Software Engineer • 広告事業, 公共事業 • データストア系OSSが好き • パフォーマンスチューニングが好き 6
  7. 7. 用語の説明
  8. 8. 用語の説明 • Graal • GraalVM • Polyglot • Truffle • Substrate VM • JVMCI, Compiler Interface • JIT Compiler • AOT • HotSpotVM 8
  9. 9. 用語の説明 • Graal • GraalVM • Polyglot • Truffle • Substrate VM • JVMCI, Compiler Interface • JIT Compiler • AOT • HotSpotVM 9
  10. 10. 用語の説明 10 HotSpot VM Compiler Interface C1 (Client) C2 (Server) • HotSpotVM C++ ← JIT Compiler 階層型コンパイラ 実行中にC1/C2両方使う
  11. 11. 用語の説明 11 HotSpot VM Compiler Interface C1 (Client) Graal • GraalVM –多言語用の仮想マシン C++ ← JIT Compiler C2の代わりにGraalを JVMCI Java JITをJavaで書くためのInterface
  12. 12. 用語の説明 12 HotSpot VM Compiler Interface C1 (Client) Graal • Graal –Javaで書かれたJITコンパイラ C++ ← JIT Compiler C2の代わりにGraalを JVMCI Java JITをJavaで書くためのInterface
  13. 13. 用語の説明 13 HotSpot VM Graal • Truffle –言語実装用フレームワーク –ASTインタプリタ C++ JVMCI Java TruffleJVM Lang Sulong(LLVM)JS R Ruby Python C, C++, Rust
  14. 14. 用語の説明 • Polyglot –他の言語を呼び出してデータのやりと りが出来る –JavaからRuby –JSからJava –などなど 14
  15. 15. 用語の説明 • AOT (Ahead of Time) –事前コンパイルの事だよ –jaotcとかjava9から入ってるよ • Substrate VM –Truffleで書かれたASTインタプリタを コンパイルしてくれる 15 https://www.oracle.com/technetwork/java/jvmls2015-wimmer-2637907.pdf
  16. 16. つまり GraalVM とは
  17. 17. GraalVM • GraalVMは –仮想マシンである –OpenJDK8と置き換える事が可能 –他の言語とコラボレーション出来る 17
  18. 18. GraalVM 18 • GraalVM –NativeImageを作れる • OneBinaryが出来る • Native Imge –起動速度が速い –メモリフットプリントが小さい
  19. 19. さっそくやってみよう
  20. 20. 開発環境の作り方 • GraalVM CE 1.0.0-RC10 を使います • OSはUbuntu18.04 20 # ダウンロード $ wget https://github.com/oracle/graal/releases/download/vm- 1.0.0-rc10/graalvm-ce-1.0.0-rc10-linux-amd64.tar.gz # 展開 $ tar zxf graalvm-ce-1.0.0-rc10-linux-amd64.tar.gz ¥ -C /usr/lib/jvm # パスを通す $ export GRAAL_HOME=/usr/lib/jvm/graalvm-ce-1.0.0-rc10 $ export PATH=$GRAAL_HOME/bin:$PATH
  21. 21. 開発環境の作り方 21 $ ls /usr/lib/jvm/graalvm-ce-1.0.0-rc10/bin/ appletviewer javah jps native-image rmiregistry extcheck javap jrunscript native2ascii schemagen gu jcmd js node serialver idlj jconsole jsadebugd npm servertool jar jdb jstack orbd tnameserv jarsigner jdeps jstat pack200 unpack200 java jhat jstatd policytool wsgen java-rmi.cgi jinfo jvisualvm polyglot wsimport javac jjs keytool rmic xjc javadoc jmap lli rmid $ node -v v10.9.0 $ java -version openjdk version "1.8.0_192" OpenJDK Runtime Environment (build 1.8.0_192- 20181024121959.buildslave.jdk8u-src-tar--b12) GraalVM 1.0.0-rc10 (build 25.192-b12-jvmci-0.53, mixed mode)
  22. 22. 開発環境の作り方 • Native buildに必要なライブラリをイ ンストールします –zlib.hが必要 22 # native buildに必要なライブラリをインストールします $ apt-get install zlib1g-dev
  23. 23. 開発環境の作り方 • 他の言語もインストールする 23 # 他の言語も使えるようにする $ gu --catalog list Downloading: Component catalog ComponentId Version Component name ---------------------------------------------------------------- python 1.0.0-rc10 Graal.Python R 1.0.0-rc10 FastR ruby 1.0.0-rc10 TruffleRuby # Install Ruby $ gu install ruby $ ${GRAAL_HOME}/jre/languages/ruby/lib/truffle/post_install_hook.sh # Install Python $ gu install python $ ruby -v ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu] $ graalpython -V Graal Python 3.7.0 (GraalVM CE Native 1.0.0-rc10)
  24. 24. サンプル
  25. 25. サンプル • 言語入り乱れて実行する(Polyglot) • Nativeイメージを作る – HelloWorld – ちょっと実用的なCLI – Redisに接続する – MySQLに接続する – SpringBootを使う – Node / Single Binary – Ruby / Single Binary 25
  26. 26. サンプル 他の言語を呼び出す
  27. 27. Sample:Polyglot • Javaから他の言語を呼び出す 27 import org.graalvm.polyglot.*; public class Sample { public static void main(String[] args) { try (Context context = Context.newBuilder().allowAllAccess(true).build()) { System.out.println( context.getEngine().getLanguages().keySet()); context.eval("ruby", "puts 'hello, ruby’”); context.eval("python", "print('hello, python')"); context.eval("js", "console.log('hello, JS¥n')"); context.eval("R", "cat('hello, R')"); } catch (PolyglotException e) { e.printStackTrace(); // こういうの本当は駄目!! } } }
  28. 28. Sample:Polyglot • 実行結果 28 [R, js, python, llvm, ruby] hello, ruby hello, python hello, JS hello, R $ javac -cp $GRAAL_HOME/jre/lib/boot/graal-sdk.jar Sample.java $ java Sample
  29. 29. Sample:Polyglot:LLVM • Javaから他の言語を呼び出す(LLVM) –BitCodeをJavaからCALLする 29 #include <stdio.h> int main() { printf("Hello from GraalVM!¥n"); return 0; } # BitCode生成 $ clang -c -O1 -emit-llvm hello.c # 実行 $ lli hello.bc Hello from GraalVM!
  30. 30. Sample:Polyglot:LLVM • Javaから他の言語を呼び出す(LLVM) 30 import org.graalvm.polyglot.*; import java.io.*; public class Sample2 { public static void main(String[] args) throws Exception { File f = new File("hello.bc"); Source source = Source.newBuilder("llvm", new File("hello.bc")).build(); try (Context context = Context.newBuilder().allowAllAccess(true).build()) { context.eval(source).execute(); } } } $ java Sample2 Hello from GraalVM!
  31. 31. Sample:Polyglot • 値を受け取る 31 import org.graalvm.polyglot.*; public class Sample3 { public static void main(String[] args) { try (Context context = Context.newBuilder().allowNativeAccess(true).build()) { Value value = context.eval("ruby", "[2,4,8]"); int v = value.getArrayElement(1).asInt(); System.out.println(v); // 4が表示される } catch (PolyglotException e) { e.printStackTrace(); // こういうの本当は駄目!! } } } $ java Sample3 4
  32. 32. Sample:Polyglot • 双方向で実行可能!! –Node から Java –Rubyから Python –などなど.. • サーバをJavaで書いてPluginを Pythonで書く等が可能 – (JRubyやJPythonで今までも出来たけど) • ちゃんと使う場合はSourceクラスを 使ったりしてキャッシュ化しましょう 32 https://www.graalvm.org/docs/reference-manual/polyglot/
  33. 33. サンプル Nativeイメージを作る
  34. 34. Sample: Nativeイメージを作る • まずは基本に忠実にHello World 34 public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } # コンパイル $ javac HelloWorld.java # 普通に実行 $ java HelloWorld Hello, World!
  35. 35. Sample: Nativeイメージを作る • Native Imageを作る – ビルドサーバが立ち上がってそこで実行される – --no-server をつけた方がトラブルが少ない – -H:Nameで出力ファイル名を指定する(省略可) 35 $ native-image –H:Name=hello --no-server HelloWorld [helloworld:5620] classlist: 1,487.46 ms [helloworld:5620] (cap): 988.10 ms [helloworld:5620] setup: 2,169.08 ms [helloworld:5620] (typeflow): 3,763.17 ms [helloworld:5620] (objects): 655.53 ms [helloworld:5620] (features): 131.40 ms [helloworld:5620] analysis: 4,616.25 ms [helloworld:5620] universe: 199.90 ms [helloworld:5620] (parse): 1,029.82 ms [helloworld:5620] (inline): 1,138.66 ms [helloworld:5620] (compile): 5,375.45 ms [helloworld:5620] compile: 7,758.60 ms [helloworld:5620] image: 247.74 ms [helloworld:5620] write: 144.12 ms [helloworld:5620] [total]: 16,690.46 ms $ ./hello Hello, World!
  36. 36. Sample: Nativeイメージを作る • 中身を確認する – Nativeイメージだけど、libcの依存がある 36 $ file ./hello ./hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=32f1dede2061d81be1f5573b20db12b9044212f7, with debug_info, not stripped $ ldd ./hello linux-vdso.so.1 (0x00007ffe5696d000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f00c17a5000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f00c159d000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f00c11ac000) /lib64/ld-linux-x86-64.so.2 (0x00007f00c1dc4000) $ ls -hs ./hello 2.2M ./hello
  37. 37. Sample: Nativeイメージを作る • Libcの依存も無くそう!! – --staticでsingle binaryが生成できる 37 $ native-image –H:Name=hello --no-server --static HelloWorld $ file ./hello ./hello: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=db0a71c9360fe7b8a21e1c5cdcedad965643152e, with debug_info, not stripped $ ldd ./hello not a dynamic executable $ ls -hs ./hello 3.4M ./hello $ ./hello Hello, World!
  38. 38. Sample: Nativeイメージを作る • Nativeイメージは起動がはやい 38 $ time java Hello real 0m0.051s user 0m0.032s sys 0m0.016s $ time ./hello real 0m0.028s user 0m0.000s sys 0m0.025s Java Native 0.051s 0.028s
  39. 39. Sample: Nativeイメージを作る • フットプリントも小さい 39 $ /usr/bin/time -f "Memory:%M KB time:%E" java HelloWorld Memory:23380 KB time:0:00.05 $ /usr/bin/time -f "Memory:%M KB time:%E" ./hello Memory:2484 KB time:0:00.02 Java Native 23,380 KB 2,484KB
  40. 40. 注意事項
  41. 41. 注意事項 • Native-imageは制限が多い – いくつか後述します – SpringBootのような凝ったライブラリは茨の道です • 頑張れば実行はできます(これも後述) – Commonsは素直な実装が多いのでおすすめ • Native-image化する時の制限です!! – GraalVMを通常のOpenJDKの代わりに使う分にはC2コ ンパイラが異なるだけなので制限はありません 41
  42. 42. サンプル CLIを作る + 外部依存ライブラリ
  43. 43. Sample: CLI • 外部依存ライブラリ有りでNativeイ メージを作る – FatJarを作るのが一番楽です – maven-shade-plugin を使います 43
  44. 44. Sample: CLI 44 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <goals><goal>shade</goal></goals> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>MyCLI</Main-Class> </manifestEntries> </transformer> </transformers> </configuration> </execution> </executions> </plugin> • FatJarにするPlugin
  45. 45. Sample: CLI 45 public class MyCLI { public static void main(String[] args) throws Exception { Options options = new Options(); options.addOption("t", false, "display current time"); options.addOption("h", false, "display help"); CommandLineParser parser = new DefaultParser(); CommandLine cmd = parser.parse( options, args ); if (cmd.hasOption("h")) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp( "mycli", options ); return; } if (cmd.hasOption("t")) { System.out.println(new Date()); return; } } }
  46. 46. Sample: CLI 46 • FatJarをnative build # FAT JARを作る $ mvn package # native-imageを作る $ native-image --no-server ¥ -jar target/mycli-1.0-SNAPSHOT.jar # 実行 $ ./mycli-1.0-SNAPSHOT –t Thu Dec 13 10:16:31 UTC 2018 # ファイルサイズ $ ls -hs ./mycli-1.0-SNAPSHOT 4.1M ./mycli-1.0-SNAPSHOT
  47. 47. サンプル Redisに接続する
  48. 48. Sample: Redis • コマンド化したいよくあるケース – サービスクラスが既に存在する – それを使った便利コマンドを作りたい – データソースにアクセス事がある • RedisやMySQLなど 48
  49. 49. Sample: Redis 49 • Jedisを使う –いくつか追加の設定が必要 –POMは省略 • JEDISの依存追加 • FatJarを作る事
  50. 50. Sample: Redis 50 • Mainのコード public class App { public static void main( String[] args ) throws Exception { Jedis jedis = new Jedis("localhost", 6379); jedis.set("foo", "bar"); String value = jedis.get("foo"); System.out.println("value: " + value); } }
  51. 51. Sample: Redis 51 • 単純にビルドしても怒られます [hello-1.0-SNAPSHOT:7248] classlist: 2,885.53 ms [hello-1.0-SNAPSHOT:7248] (cap): 1,210.36 ms [hello-1.0-SNAPSHOT:7248] setup: 2,941.58 ms SLF4J: slf4j-api 1.6.x (or later) is incompatible with this binding. SLF4J: Your binding is version 1.5.5 or earlier. SLF4J: Upgrade your binding to version 1.6.x. [hello-1.0-SNAPSHOT:7248] analysis: 6,413.27 ms error: Class initialization failed: redis.clients.jedis.HostAndPort Detailed message: Error: Class initialization failed: redis.clients.jedis.HostAndPort Original exception that caused the problem: java.lang.NoSuchMethodError: org.slf4j.impl.StaticLoggerBinder.getSingleton()Lorg/slf4j/impl/StaticLogger Binder; at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
  52. 52. Sample: Redis 52 • リフレクションやDynamicProxyの制限 –外部設定でいろいろ指定してあげる –初期化を遅延させたり $ native-image --no-server ¥ --allow-incomplete-classpath ¥ --delay-class-initialization-to- runtime=redis.clients.jedis.HostAndPort ¥ -jar target/hello-1.0-SNAPSHOT.jar
  53. 53. Sample: Redis 53 • これでRedisの利用はできます • このようにLogger, リフレクション, Proxy を利用しているところは、外から設定を追 加していく必要があります。 $ ./hello-1.0-SNAPSHOT value: bar
  54. 54. サンプル MySQL JDBC Driver
  55. 55. Sample: MySQL JDBC Driver 55 • JDBCをNativeImage化するのは辛みがあ る!! Class.forName("com.mysql.cj.jdbc.Driver"); String url = “jdbc:mysql://127.0.0.1:3306/mysql?..(省略)"; try (Connection conn = DriverManager.getConnection(url, "root", "" )) { try (PreparedStatement pst = conn.prepareStatement("select help_keyword_id, name from mysql.help_keyword")) { try (ResultSet rs = pst.executeQuery()) { while (rs.next()) { int id = rs.getInt(1); String name = rs.getString(2); System.out.printf("%10d -> %s%n", id, name); } } } }
  56. 56. Sample: MySQL JDBC Driver 56 • リフレクションで生成されるクラスを書い ていく -H:ReflectionConfigurationFiles=app.json [ { "name" : "com.mysql.cj.conf.url.SingleConnectionUrl", "allDeclaredConstructors" : true, "allPublicConstructors" : true, "allDeclaredMethods" : true, "allPublicMethods" : true }, /* … */ ]
  57. 57. Sample: MySQL JDBC Driver 57 • 例えば、接続URLによって5種類の ConnectionUrlクラスを動的に生成する https://github.com/mysql/mysql-connector-j/blob/8.0.13/src/main/ core-api/java/com/mysql/cj/conf/ConnectionUrl.java#L199
  58. 58. Sample: MySQL JDBC Driver 58 • ひたすら書いていく.. [ { "name" : "com.mysql.cj.conf.url.SingleConnectionUrl", }, { "name" : "com.mysql.cj.conf.url.FailoverConnectionUrl", }, { "name" : "com.mysql.cj.conf.url.LoadbalanceConnectionUrl", }, { "name" : "com.mysql.cj.conf.url.ReplicationConnectionUrl", }, ]
  59. 59. Sample: MySQL JDBC Driver 59 • 時にはクラスを書き換える!! import com.oracle.svm.core.annotate.*; @TargetClass(com.mysql.cj.log.LogFactory.class) final class my_replace_test1 { @Substitute public static Log getLogger(String className, String instanceName) { //return new com.mysql.cj.log.NullLogger(instanceName); return new com.mysql.cj.log.StandardLogger(instanceName); } } https://github.com/mysql/mysql-connector-j/blob/8.0.13/src/main/core-impl/java/com/mysql/cj/log/LogFactory.java
  60. 60. Sample: MySQL JDBC Driver 60 • Compile時に実装を乗っ取ることができる – AOPのCompile Time版みたいなイメージ import com.oracle.svm.core.annotate.*; @TargetClass(com.mysql.cj.log.LogFactory.class) final class my_replace_test1 { @Substitute public static Log getLogger(String className, String instanceName) { //return new com.mysql.cj.log.NullLogger(instanceName); return new com.mysql.cj.log.StandardLogger(instanceName); } } • jre/lib/svm/builder/svm.jarをリンクする
  61. 61. Sample: MySQL JDBC Driver 61 • StandardSocketFactory • NativeProtocol • このあたりまで潜ったけど、connection errorを解決できず.. time over 誰か挑戦してください!!
  62. 62. SpringBootを使う
  63. 63. Sample: SpringBoot 63 • こちらを参照ください – https://github.com/dsyer/spring-boot-micro-apps/ • ちゃんと動いている • すごい頑張っている..
  64. 64. Sample: SpringBoot 64 SpringBootが40msで起動している スゴイ!!
  65. 65. Sample: SpringBoot 65 • でも昨日試したらLogger周りでエラー出る !
  66. 66. サンプル NodeJSのSingle Binary生成
  67. 67. Sample: NodeJS Single Binary 67 • 今までの機能を使えばNodeJSでも SingleBinaryが作れるのでは? できます!!
  68. 68. Sample: NodeJS Single Binary 68 • Polyglotでjsを呼び出すサンプル import org.graalvm.polyglot.*; public class JSNative { public static void main(String[] args) { try (Context context = Context.create("js")) { context.eval("js", "console.log('hello');"); } catch (PolyglotException e) { e.printStackTrace(); } } }
  69. 69. Sample: NodeJS Single Binary 69 • ビルドする – めっちゃ重い – メモリ6GBくらい消費する – CPUもほぼ全部ぶんまわる $ javac -cp $GRAAL_HOME/jre/lib/boot/graal-sdk.jar JSNative.java $ native-image --language:js --tool:truffle --no-server JSNative
  70. 70. Sample: NodeJS Single Binary 70 • できた!! – サイズはでかい.. $ ./jsnative hello $ ls -hs ./jsnative 65M ./jsnative
  71. 71. サンプル RubyのSingle Binary生成
  72. 72. Sample: Ruby Single Binary 72 • 同じ感じで出来ます $ javac -cp $GRAAL_HOME/jre/lib/boot/graal-sdk.jar RubyNative.java $ native-image --language:ruby --tool:truffle --no-server RubyNative
  73. 73. Sample: Ruby Single Binary 73 • 今はNodeやRubyを直接Native化でき ない • JavaからPolyglot使えば出来る
  74. 74. 制限事項
  75. 75. 制限事項 • 基本的にはここに書いてあります • https://github.com/oracle/graal/blob/master/substratevm/LIMITATIONS.md • いくつかピックアップ –Static Initializer –Synchronized –Lambda/INDY –Dynamic Proxy / Reflection 75
  76. 76. 制限事項: static initializer
  77. 77. 制限事項: Static Initializer • CompileTimeに実行される –動的な処理は避ける 77 public class StaticInitializersSample { private static final int MyConstInt; private static final String MyConstString; static { MyConstInt = 20181215; MyConstString = "JJUG CCC"; System.out.println("static init"); } public static void main(String[] args) { System.out.println(MyConstInt); System.out.println(MyConstString); System.out.println("main print"); } }
  78. 78. 制限事項: Static Initializer • ビルド 78 $ javac StaticInitializersSample.java $ native-image StaticInitializersSample Build on Server(pid: 14906, port: 46301) [staticinitializerssample:14906] classlist: 251.47 ms [staticinitializerssample:14906] (cap): 645.03 ms [staticinitializerssample:14906] setup: 942.31 ms static init [staticinitializerssample:14906] (typeflow): 2,296.96 ms … コンパイル時に実行される
  79. 79. 制限事項: Static Initializer • 実行 79 $ ./staticinitializerssample 20181215 JJUG CCC main print static {} は実行されない!! → static initは表示されない
  80. 80. 制限事項: Static Initializer • こういうコードは危険 80 public class MyInit { private static String defaultEnv = "dev"; static { String env = System.getenv("MY_ENV"); if (env != null) defaultEnv = env; } public static void main(String[] args) { System.out.println("env=" + defaultEnv); } } $ java MyInit env=dev $ MY_ENV=stg java MyInit env=stg Java
  81. 81. 制限事項: Static Initializer • こういうコードは危険 81 public class MyInit { private static String defaultEnv = "dev"; static { String env = System.getenv("MY_ENV"); if (env != null) defaultEnv = env; } public static void main(String[] args) { System.out.println("env=" + defaultEnv); } } $ MY_ENV=prod native-image --no-server MyInit $ ./myinit env=prod $ MY_ENV=stg ./myinit env=prod Native
  82. 82. 制限事項: Static Initializer • 回避策 – --rerun-class-initialization-at-runtime – カンマ区切りでクラスを渡す – 実行時にstatic initializerを実行する 82 $ native-image ¥ --rerun-class-initialization-at-runtime=MyInit ¥ --no-server MyInit $ ./myinit env=prod $ MY_ENV=dev ./myinit env=dev
  83. 83. 制限事項: synchronized
  84. 84. 制限事項: synchronized • java.util.concurrent.locksが利用される – エスケープ解析が実行されないので、不要な同期処理で も実行されてしまう – HotSpot VMよりも不利 84
  85. 85. 制限事項: synchronized 85 import java.util.ArrayList; public class Sync2 { static String hoge() { ArrayList<String> v = new ArrayList<>(); v.add("Me"); v.add("You"); v.add("Her"); return v.toString(); } public static void main(String[] args) { for (int i = 0; i < 10000000; i++) { String v = hoge(); } } } real 0m2.099s user 0m3.578s sys 0m0.393s real 0m1.700s user 0m1.591s sys 0m0.102s Java Native Synchronized無しは Nativeの方が若干速いけど、
  86. 86. 制限事項: synchronized 86 import java.util.Vector; public class Sync2 { static String hoge() { Vector<String> v = new Vector<>(); v.add("Me"); v.add("You"); v.add("Her"); return v.toString(); } public static void main(String[] args) { for (int i = 0; i < 10000000; i++) { String v = hoge(); } } } real 0m2.075s user 0m3.789s sys 0m0.238s real 0m4.004s user 0m3.901s sys 0m0.090s Java Native Synchronizedがあると、 Nativeはとても遅い!!
  87. 87. 制限事項: Lambda/INDY
  88. 88. 制限事項: Lambda/Indy • InvokeDynamicはサポートされない • LambdaはInvokeDynamic –Lambda自体はサポートされる • RunTimeではなくCompileTime 88
  89. 89. 制限事項: Dynamic Proxy / Reflection
  90. 90. 制限事項:Dynamic Proxy/Reflection • 今までのサンプルを見て分かったと思 います.. • 詳細はこちらを – https://github.com/oracle/graal/blob/master/substratevm/DYNAMIC_PROXY.md 90
  91. 91. まとめ
  92. 92. まとめ • GraalVMは日々進化しています – まだ出来ない事も多い – そのうち出来るようになる • Polyglot / Native Imageで Happy Hacking!! 92

×