Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Wirklich so schnell? Performance von Native Images auf der GraalVM

Wirklich so schnell? Performance von Native Images auf der GraalVM

Vortrag beim JavaLand 2022, 16. März 2022

https://shop.doag.org/javaland/2022/agenda/#textSearch.Lehmann

Die GraalVM ist eine - gar nicht mal so neue - Java VM, die Schritt für Schritt immer mehr Produktionsreife und Popularität bei Entwicklern und Architekten gewinnt. Graal verspricht bessere Performance durch den Build von Native Images, v.a. schnellen Startup und geringen Speicherverbrauch, indem wir Java-Code "ahead-of-time" nach Native-Code kompilieren.
Wir kompilieren also unseren Sourcecode nicht mehr in guten alten Bytecode, stattdessen in rasend schnellen Maschinencode?

Wir zeigt anhand verschiedener Messungen, ob und wie gut die GraalVM Native Images dieses Versprechen wirklich einlösen können und unterscheiden kurzläufiges Startupverhalten von langläufigem Laufzeitverhalten und betrachten den Speicherverbrauch.
Und nichts kommt ohne Preis: Wir zeigen, welche Fallen (z.B. bei Reflection-Nutzung) zur Build- und zur Runtime lauern, wenn ein solches Native Image erstellt bzw. ausgeführt wird. Und wie testet man das eigentlich alles?

Martin Lehmann

March 16, 2022
Tweet

More Decks by Martin Lehmann

Other Decks in Technology

Transcript

  1. Copyright © Accso – Accelerated Solutions GmbH 1 v.3 v.3.18

    Wirklich so schnell? Performance von Native Images auf der Startup, Laufzeit, Speicherverbrauch von GraalVM Native Images MARTIN LEHMANN JAVALAND 2022, MÄRZ 2022 @mrtnlhmnn
  2. Copyright © Accso – Accelerated Solutions GmbH 2 Martin Lehmann

    Accso - Accelerated Solutions GmbH Cheftechnologe Martin Lehmann ist Diplom-Informatiker und als Cheftechnologe und Softwarearchitekt bei der Accso – Accelerated Solutions GmbH tätig. Seit Ende der 90er-Jahre arbeitet er als Softwareentwickler und -architekt in der Softwareentwicklung in diversen Projekten der Individualentwicklung für Kunden verschiedener Branchen. Seit den Zeiten von Java 1.0 beschäfigt er sich mit Java als Programmiersprache und als Ökosystem. [email protected] @mrtnlhmnn xing.to/mle
  3. Copyright © Accso – Accelerated Solutions GmbH 3 https://shop.doag.org/javaland/2022/agenda/#textSearch.Lehmann Die

    GraalVM ist eine - gar nicht mal so neue - Java VM, die Schritt für Schritt immer mehr Produktionsreife und Popularität bei Entwicklern und Architekten gewinnt. Graal verspricht bessere Performance durch den Build von Native Images, v.a. schnellen Startup und geringen Speicherverbrauch, indem wir Java-Code "ahead-of-time" nach Native-Code kompilieren. Wir kompilieren also unseren Sourcecode nicht mehr in guten alten Bytecode, stattdessen in rasend schnellen Maschinencode? Wir zeigt anhand verschiedener Messungen, ob und wie gut die GraalVM Native Images dieses Versprechen wirklich einlösen können und unterscheiden kurzläufiges Startupverhalten von langläufigem Laufzeitverhalten und betrachten den Speicherverbrauch. Und nichts kommt ohne Preis: Wir zeigen, welche Fallen (z.B. bei Reflection-Nutzung) zur Build- und zur Runtime lauern, wenn ein solches Native Image erstellt bzw. ausgeführt wird. Und wie testet man das eigentlich alles? Abstract
  4. Copyright © Accso – Accelerated Solutions GmbH 4 Test und

    einige Fallen Performance: Wie schnell ist das wirklich? Einführung: Graal? Native-Image! Fazit
  5. Copyright © Accso – Accelerated Solutions GmbH 5 im Überblick

    General Recursive Applicative and Algorithmic Language GraalVM = Universal Virtual Machine für Anwendungen von JVM-basierten Sprachen wie Java, Scala, Clojure, Kotlin, … von JavaScript, Python, Ruby, R von LLVM-basierte Sprachen wie C und C++ Anwendungen entweder im JVM- Modus oder als Native-Images http://graalvm.org https://github.com/oracle/graal Aktuell ist Version 22.0.0.2 Community (CE) und Enterprise Edition (EE) für Java11 und 17 Lizenzen siehe Übersicht auf Github https://www.graalvm.org/reference- manual/native-image/ https://www.graalvm.org/examples/na tive-image-examples/ Graal und GraalVM Versionen
  6. Copyright © Accso – Accelerated Solutions GmbH 6 baut Native-Images,

    nutzt SubstrateVM Gebaut wird ein Standalone Executable. Alternativ kann man auch eine Shared Library erstellen. Closed-world assumption: Alle Klassen, alles an Bytecode muss zur Build-Zeit bekannt sein. Optimierungen nur zur Build-Zeit, nicht mehr zur Laufzeit. Cross-Compile ist z.Zt. nicht möglich. Alle Anwendungsklassen über alle transitiven Abhängigkeiten, ausgehend von einer Main-Class Native-Image benötigt zur Laufzeit keine (separate) JVM, stattdessen: SubstrateVM = interne Runtime, in der AOT-kompilierter Code ohne (separate) JVM ausgeführt wird Memory Management Thread Scheduling Garbage Collector (Default: Serial GC) Ahead-of-Time Compile AOT Was wird mit verpackt?
  7. Copyright © Accso – Accelerated Solutions GmbH 7 Die Zahlen

    in diesem Vortrag benutzen und vermessen dieses Setup: • Windows 10 mit WSL2 (Linux/Ubuntu) • GraalVM 22.0 Community Edition (CE) für Java 17 • Enterprise Edition (EE) für Java 17 • Eclipse Adoptium 11.0.14.9 und 17.0.2.8 Alle Beispiele auf Github: https://github.com/accso/graalvm-native Viele Optionen – unsere Beispiele auf Github 21.1|2|3 22.0 CE EE Java 8 Java 11 Java 16 Java 17 JVM-Modus Native-Image Build- und Laufzeit- Optimierungen
  8. Copyright © Accso – Accelerated Solutions GmbH 8 Beispiel „mandelbrot“

    • Linker-Fehler mit 21.1.0, JDK 16, Enterprise Edition Beispiel „quarkus-timeserver“ • PGO-Optimierung führt zu Laufzeit-Segfault unter 21.1.0/11/EE Nicht alle Beispiele funktionieren in allen Varianten [ [ SubstrateSegfaultHandler caught a segfault. ] ] Fatal error:java.lang.RuntimeException: java.lang.RuntimeException: There was an error linking the native image: Linker command exited with 1 /usr/bin/ld: /opt/graalvm-ee-java16-21.1.0/lib/static/linux- amd64/glibc/libjavajpeg.a(jpegdecoder.o):(.bss.jvm+0x0): multiple definition of `jvm'; /opt/graalvm- ee-java16-21.1.0/lib/static/linux-amd64/glibc/libawt.a(awt_LoadLibrary.o):(.bss.jvm+0x0): first defined here collect2: error: ld returned 1 exit status
  9. Copyright © Accso – Accelerated Solutions GmbH 9 Kurzer Umgebungscheck

    lehmann@edwards03:~/graal/graalvm-native $ $ echo $GRAALVM_HOME /opt/graalvm-ce-java17-22.0.0.2 lehmann@edwards03:~/graal/graalvm-native $ $ $GRAALVM_HOME/bin/java -version openjdk version "17.0.2" 2022-01-18 OpenJDK Runtime Environment GraalVM CE 22.0.0.2 (build 17.0.2+8-jvmci-22.0-b05) OpenJDK 64-Bit Server VM GraalVM CE 22.0.0.2 (build 17.0.2+8-jvmci-22.0-b05, mixed mode, sharing)
  10. Copyright © Accso – Accelerated Solutions GmbH 10 Kurzer Umgebungscheck

    lehmann@edwards03:~/graal/graalvm-native $ $ echo $GRAALVM_HOME /opt/graalvm-ce-java17-22.0.0.2 lehmann@edwards03:~/graal/graalvm-native $ $ $GRAALVM_HOME/bin/java -version openjdk version "17.0.2" 2022-01-18 OpenJDK Runtime Environment GraalVM CE 22.0.0.2 (build 17.0.2+8-jvmci-22.0-b05) OpenJDK 64-Bit Server VM GraalVM CE 22.0.0.2 (build 17.0.2+8-jvmci-22.0-b05, mixed mode, sharing) lehmann@edwards03:~/graal/graalvm-native $ $ $GRAALVM_HOME/bin/gu list … ComponentId Version Component name Stability Origin ---------------------------------------------------------------------------------- native-image 22.0.0.2 Native Image Experimental …
  11. Copyright © Accso – Accelerated Solutions GmbH 11 Beispiel „HelloWorld“

    und Build-Skript public class HelloWorld { HelloWorld.java public static void main(String[] args) { System.out.println("Hello, World!"); } } SRC=./src build.sh TARGET=./target mkdir -p ${TARGET} ${GRAALVM_HOME}/bin/javac -d ${TARGET} ${SRC}/HelloWorld.java ${GRAALVM_HOME}/bin/native-image --no-fallback \ -H:+PrintAnalysisCallTree \ -H:+PrintAnalysisStatistics \ -H:+ReportExceptionStackTraces \ HelloWorld helloworld native-image baut aus .class/.jar-Dateien das Native-Image als Binary Executable
  12. Copyright © Accso – Accelerated Solutions GmbH 12 GraalVM Native

    Build-Tools für Maven & Gradle <plugin> pom.xml <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> <version>0.9.9version> … <configuration> <imageName>helloworld</imageName> <mainClass>HelloWorld</mainClass> <buildArgs> <buildArg>--no-fallback</buildArg> <buildArg>-H:+PrintAnalysisCallTree</buildArg> <buildArg>-H:+PrintAnalysisStatistics</buildArg> <buildArg>-H:+ReportExceptionStackTraces</buildArg> <buildArg>--report-unsupported-elements-at-runtime</buildArg> <!-- Enterprise Edition: might want to use G1GC --> <!--buildArg>--gc=G1</buildArg--> </buildArgs> </configuration> </plugin> https://github.com/graalvm/native-build-tools
  13. Copyright © Accso – Accelerated Solutions GmbH 13 Native-Image-Builds sind

    laaangsam lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ . ./build.sh Beim Bauen können ausführliche Reports erzeugt werden, u.a. für • Call Tree • Used Classes • Uses Packages • Used Methods Der Build-Output wurde in G22 deutlich erweitert und verbessert.
  14. Copyright © Accso – Accelerated Solutions GmbH 17 Native-Image: Start,

    Größe, File-Type lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ ./target/helloworld Hello, World! lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ ls -laF target/* -rw-r--r-- 1 lehmann lehmann 427 Feb 7 17:21 target/HelloWorld.class -rwxr-xr-x 1 lehmann lehmann 12M Feb 7 17:22 target/helloworld* lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ file ./target/helloworld ./target/helloworld: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=8e6d8784b05cdc7bab6b126c97c044b22116d18b, for GNU/Linux 3.2.0, with debug_info, not stripped
  15. Copyright © Accso – Accelerated Solutions GmbH 18 Native-Image: Welche

    Java-Version? lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ strings ./target/helloworld | grep com.oracle.svm.core.VM com.oracle.svm.core.VM.Target.Libraries=pthread|dl|z|rt com.oracle.svm.core.VM.Target.LibC=com.oracle.svm.core.posix.linux.libc.GLibC com.oracle.svm.core.VM.Java.Version=17.0.2 com.oracle.svm.core.VM.Target.CCompiler=gcc|linux|x86_64|9.3.0 com.oracle.svm.core.VM.Target.Platform=org.graalvm.nativeimage.Platform$LINUX_A MD64 com.oracle.svm.core.VM=GraalVM 22.0.0.2 Java 17 CE com.oracle.svm.core.VM.Target.StaticLibraries=liblibchelper.a|libnet.a|libnio.a |libjava.a|libfdlibm.a|libzip.a|libjvm.a
  16. Copyright © Accso – Accelerated Solutions GmbH 19 Test und

    einige Fallen Performance: Wie schnell ist das wirklich? Einführung: Graal? Native-Image! Fazit
  17. Copyright © Accso – Accelerated Solutions GmbH 20 Twitter nutzt

    Graal schon produktiv https://www.constellationr.com/research/how-oracle-graal-supercharged-twitter-s-microservices-platform
  18. Copyright © Accso – Accelerated Solutions GmbH 23 native-image hat

    ca. 850 Experten-Optionen lehmann@edwards03:~/graal/graalvm-native $ $ $GRAALVM_HOME/bin/native-image --expert-options-all | grep -ic optimiz … ... 40 verschiedene Argumente ..., z.B. -H:Optimize=2 Control native-image code optimizations: 0 - no optimizations, 1 - basic optimizations, 2 - aggressive optimizations lehmann@edwards03:~/graal/graalvm-native $ $ $GRAALVM_HOME/bin/native-image --expert-options-all | grep -ic print … ... 98 verschiedene Argumente ... Vermutlich ist „aggressive“ der Default.
  19. Copyright © Accso – Accelerated Solutions GmbH 25 Startup-Zeiten von

    „helloworld“ time java -cp target HelloWorld run.sh time ./target/helloworld (und run-loop*.sh mit Schleife…) lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ . ./run-loop_jvm.sh 100 real 0m3.408s user 0m2.322s sys 0m0.977s lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ . ./run-loop_graal-jvm.sh 100 real 0m9.493s lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ . ./run-loop_graal-native.sh 100 real 0m0.150s Graal 22 native 17 Graal 22 JVM 17 Eclipse Temurin Adoptium JVM 17
  20. Copyright © Accso – Accelerated Solutions GmbH 26 Startup des

    Native-Images ist signifikant schneller. Startup-Zeit Native-Image ist signifikant schneller im Startup als die JVMs In HelloWorld-Beispiel mit Faktor 20-60! Da alles in das Native- Image verpackt ist, muss insbesondere keine JVM hochfahren. Memory Laufzeit
  21. Copyright © Accso – Accelerated Solutions GmbH 27 Startup-Zeit Native-Image

    ist signifikant schneller im Startup als die JVMs In HelloWorld-Beispiel mit Faktor 20-60! Da alles in das Native- Image verpackt ist, muss insbesondere keine JVM hochfahren. Memory Laufzeit Memory-Footprint am Beispiel 1) „helloworld“ Memory-Footprint am Beispiel 2) „mandelbrot“ Native-Images haben ein optimiertes Memory-Footprint.
  22. Copyright © Accso – Accelerated Solutions GmbH 28 Memory von

    Beispiel 1 „helloworld“ lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ /usr/bin/time --format %M java -cp target/ HelloWorld 37324 lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ /usr/bin/time --format %M java -cp target/ HelloWorld 41508 lehmann@edwards03:~/graal/graalvm-native/helloworld $ $ /usr/bin/time --format %M ./target/helloworld 7400 %M = Maximum resident set size of the process during its lifetime, in Kilobytes. Graal 22 JVM 17 Graal 22 native 17 Eclipse Temurin Adoptium JVM 17
  23. Copyright © Accso – Accelerated Solutions GmbH 29 Memory von

    Beispiel 2 „mandelbrot“ Graal 22 JVM 17
  24. Copyright © Accso – Accelerated Solutions GmbH 30 Memory von

    Beispiel 2 „mandelbrot“ Graal 22 native 17
  25. Copyright © Accso – Accelerated Solutions GmbH 31 Startup-Zeit Native-Image

    ist signifikant schneller im Startup als die JVMs In HelloWorld-Beispiel mit Faktor 20-60! Da alles in das Native- Image verpackt ist, muss insbesondere keine JVM hochfahren. Performance am Beispiel 2) „mandelbrot“ Durchsatz am Beispiel 3) „quarkus-timeserver“ Laufzeit Auf lange Sicht ist die JVM durch Just-in-time- Optimierungen schneller als das Native-Images. Memory Memory-Footprint am Beispiel 1) „helloworld“ Memory-Footprint am Beispiel 2) „mandelbrot“
  26. Copyright © Accso – Accelerated Solutions GmbH 32 Laufzeit für

    Beispiel 1) „filefinder“ time java -cp target FileFinder ${DIR} -name ${PATTERN} run.sh time ./target/filefinder ${DIR} -name ${PATTERN} time ./target/filefinderWithJS ${DIR} -name ${PATTERN} lehmann@edwards03:~/graal/graalvm-native/filefinder $ $ . ./run.sh /usr "*.h" 2>&1 | grep real real 0m11.092s // Graal/JVM-Modus real 0m10.886s // Graal/Native-Image real 0m11.549s // Graal/Native-Image // mit JavaScript Laufzeit für das Native-Image im Vergleich zum JVM-Modus gut – aber Startup dominiert. Graal 22 JVM 17 Graal 22 native 17
  27. Copyright © Accso – Accelerated Solutions GmbH 33 Laufzeit für

    Beispiel 2) „mandelbrot“ • Apfelmännchen wird in entweder „in Memory“ in Bild-Puffer oder als PNG-Datei erzeugt (mit ImageIO und AWT) • In 20 und 21 kamen zum Teil Laufzeitfehler bei der Bild-Erzeugung (UnsatisfiedLinkError, Probleme mit JNI, Segfaults bei PGO) • In Graal 22 keine Probleme mehr damit
  28. Copyright © Accso – Accelerated Solutions GmbH 34 Exception in

    thread "main" java.lang.NoSuchFieldError: java.awt.image.ColorModel.pData at com.oracle.svm.jni.functions.JNIFunctions$Support .getFieldID(JNIFunctions.java:1125) … at java.awt.image.ColorModel.<clinit>(ColorModel.java:220) Laufzeitfehler für „mandelbrot“ bei Graal 20 und 21 • Performance-Messungen nur „in Memory“ mit Bild-Puffer • Native-Image erlaubt nicht per se Bild-Erzeugung mit ImageIO/AWT. Build funktioniert in Graal 20.3 / JDK11, aber dann Laufzeitfehler: • In 21.1 kommt ohne JNI-Konfiguration dieser Laufzeitfehler: Exception in thread "main" java.lang.UnsatisfiedLinkError: no awt in java.library.path at com.oracle.svm.core.jdk.NativeLibrarySupport. loadLibrary(NativeLibrarySupport.java:131) at java.lang.ClassLoader.loadLibrary(ClassLoader. java:270) 20.2 21.1
  29. Copyright © Accso – Accelerated Solutions GmbH 35 Laufzeit für

    Beispiel 2) „mandelbrot“ • Alle nachstehenden Zahlen nur für die In-Memory- Variante • Performance der Native- Images ist in Graal 22 deutlich besser als in Vorgänger-Versionen 20 und 21
  30. Laufzeit in Sekunden (weniger ist besser) Komplexitätsfaktor: Mandelbrot-Bild wird in

    Memory als Vielfaches von 1024 erzeugt EE 21 JVM EE 21 native CE 21 JVM CE 21 native Adopt 11 Adopt 16
  31. Laufzeit in Sekunden (weniger ist besser) abgeschnitten EE 21 JVM

    EE 21 native CE 21 JVM CE 21 native Adopt 11 Adopt 16 21.1.0 CE JVM-Modus ist Faktor 2 bis 5 schneller als das Native-Image
  32. Faktor 5 Faktor 2 35 s Laufzeit in Sekunden (weniger

    ist besser) 197 s EE 21 JVM EE 21 native CE 21 JVM CE 21 native Adopt 11 Adopt 16 21.1.0 CE JVM-Modus ist Faktor 2 bis 5 schneller als das Native-Image
  33. Faktor 5 Faktor 2 35 s Laufzeit in Sekunden (weniger

    ist besser) 197 s EE 21 JVM EE 21 native CE 21 JVM CE 21 native Adopt 11 Adopt 16 21.1.0 CE JVM-Modus ist Faktor 2 bis 5 schneller als das Native-Image
  34. 82 s 30 s Laufzeit in Sekunden (weniger ist besser)

    EE 21 JVM EE 21 native CE 21 JVM CE 21 native Adopt 11 Adopt 16 21.1.0 EE Gleiches Bild für EE, aber insgesamt schneller als CE Faktor 2,6 197 s 35 s
  35. Laufzeit in Sekunden (weniger ist besser) 64 s 39 s

    EE 21 JVM EE 21 native CE 21 JVM CE 21 native Adopt 11 Adopt 16 21.1.0 CE Optimierung „Complex/Mutable“ macht CE Native 3x schneller, bewirkt bei EE aber gar nichts. Faktor 1,6 197 s 35 s
  36. 29 s Laufzeit in Sekunden (weniger ist besser) 80 s

    EE 21 JVM EE 21 native CE 21 JVM CE 21 native Adopt 11 Adopt 16 21.1.0 EE Diese Optimierung „Complex/Mutable“ bewirkt bei EE nichts Faktor 2,7 197 s 35 s
  37. 80 s 64 s 39 s 29 s 82 s

    35 s 30 s Laufzeit in Sekunden (weniger ist besser) Complex ist immutable Complex ist mutable 197 s EE 21 JVM EE 21 native CE 21 JVM CE 21 native Adopt 11 Adopt 16 In Graal 21 ist der JVM-Modus schneller als das Native-Image. EE ist schneller als CE. Mutable-Pattern hilft (nicht immer).
  38. In Graal 21 ist der JVM-Modus schneller als das Native-Image.

    EE ist schneller als CE. Mutable-Pattern hilft (nicht immer). Graals JVM-Modus ist schneller als Adopt OpenJDK 11 und 16. 80 s 64 s 39 s 29 s 82 s 35 s 30 s 52 s 52 s 41 s 43 s Laufzeit in Sekunden (weniger ist besser) Complex ist immutable Complex ist mutable 197 s EE 21 JVM EE 21 native CE 21 JVM CE 21 native Adopt 11 Adopt 16
  39. Laufzeit in Sekunden (weniger ist besser) EE 22 nat. PGO

    Temurin 11 Temurin 17 22.0.0.2 CE In Graal 22 und JDK 17 ist die Laufzeit-Performance von Native-Images sehr viel schneller geworden, etwa Faktor 5. Aber immer noch langsamer als JVM-Modus. 197 s 35 s 38 s 34 s EE 22 JVM EE 22 native CE 22 JVM CE 22 native
  40. 82 s 30 s Laufzeit in Sekunden (weniger ist besser)

    39 s 30 s 36 s EE 22 nat. PGO Temurin 11 Temurin 17 EE 22 JVM EE 22 native CE 22 JVM CE 22 native 22.0.0.2 EE Gleiches gilt auch für die Laufzeit-Performance von Native-Images bei der Enterprise Edition. Hier etwa Faktor 2. Auch auch hier immer noch langsamer als JVM-Modus. PGO-Optimierung bringt dabei nur wenig.
  41. 35 s 34 s 30 s 39 s 34 s

    30 s 64 s 60 s 37 s 38 s Laufzeit in Sekunden (weniger ist besser) Complex ist immutable Complex ist mutable 38 s 38 s EE 22 nat. PGO Temurin 11 Temurin 17 EE 22 JVM EE 22 native CE 22 JVM CE 22 native In Graal 22 ist JVM-Modus noch leicht schneller als Native-Image. EE ist kaum schneller als CE. Graals JVM-Modus ist schneller als Eclipse Temurin 11 und 17.
  42. Durchsatz / Sekunde (mehr ist besser) Graal 21.1.0 CE und

    EE mit JDK 11: JVM-Modus ist signifikant schneller als das Native-Image EE JVM EE native CE JVM CE native 8.400/s 11.500/s 11.600/s 7.500/s -35% -25%
  43. Durchsatz / Sekunde (mehr ist besser) Graal 22.0.0.2 CE und

    EE mit JDK 17: JVM-Modus ist signifikant schneller als das Native-Image Und Graal 22 ist nun langsamer als Graal 21. EE JVM EE native CE JVM CE native 6.250/s 8.500/s 8.750/s 5.750/s -45% -40%
  44. Copyright © Accso – Accelerated Solutions GmbH 53 Test und

    einige Fallen Performance: Wie schnell ist das wirklich? Einführung: Graal? Native-Image! Fazit
  45. Copyright © Accso – Accelerated Solutions GmbH 54 Alternativ: Native-Image-Tests

    mit Junit. Und: Quarkus bietet @NativeImageTest. (siehe Github-Beispiele) Wie testet man ein Native-Image? Funktionale Tests nur mit dem Java-Build Erste Smoke-Tests mit dem N.I. Integrations- tests mit dem N.I. Erkennt funktionale Fehler (früh), wie bisher Nutzt bestehende Pipeline und Test- Automatisierung Erkennt Fehler beim Build des N.I. Insbesondere dynamische Aspekte wie Reflection & Co Erkennt, wenn Abhängigkeiten nicht richtig ins N.I. verpackt wurden. Fallback-Falle! Auf Zielumgebung bzw. in Docker & Co
  46. Copyright © Accso – Accelerated Solutions GmbH 55 Dynamische Aspekte,

    die erst zur Laufzeit zum Tragen kommen und daher AOT nicht / unzureichend bekannt bzw. optimiert werden können: ✓ Reflection ✓ Property-Handling ✓ Resource-Handling Siehe Github-Beispiele „reflection“, „properties“, „resources“ „dynamicproxy“ AOT muss alles Nötige bekannt sein, damit das Native-Image vollständig ist. Dabei hilft ein Java-Agent, der – beim normalen JVM-Start – die nötigen Infos (z.B. für Reflection) einmalig mitschneidet und als JSON-Dateien rausschreibt. Vollständigkeit hängt natürlich von Coverage ab! Dynamische Aspekte müssen AOT bekannt sein ✓ Dynamic Proxy ✓ JNI X Byte-Code-Enhancement
  47. Copyright © Accso – Accelerated Solutions GmbH 56 Beispiel „reflection“:

    Java-Agent erzeugt JSON-Files build3_with-reflect-config.sh (gekuerzt) # create META-INF/native-image/reflect-config.json (note: "output-dir") ${GRAALVM_HOME}/bin/java \ -agentlib:native-image-agent=config-output-dir=./META-INF/native-image \ ReflectionCaller StringManipulator reverse "hello" # ... and then append to it in the second run (note: "merge-dir") ${GRAALVM_HOME}/bin/java \ -agentlib:native-image-agent=config-merge-dir=./META-INF/native-image \ ReflectionCaller StringManipulator capitalize "world"
  48. Copyright © Accso – Accelerated Solutions GmbH 57 Beispiel „reflection“:

    Java-Agent erzeugt JSON-Files build3_with-reflect-config.sh (gekuerzt) # create META-INF/native-image/reflect-config.json (note: "output-dir") ${GRAALVM_HOME}/bin/java \ -agentlib:native-image-agent=config-output-dir=./META-INF/native-image \ ReflectionCaller StringManipulator reverse "hello" # ... and then append to it in the second run (note: "merge-dir") ${GRAALVM_HOME}/bin/java \ -agentlib:native-image-agent=config-merge-dir=./META-INF/native-image \ ReflectionCaller StringManipulator capitalize "world" lehmann@edwards03:~/graal/graalvm-native/reflection $ $ ls target/META-INF/native-image jni-config.json proxy-config.json resource-config.json predefined-classes-config.json reflect-config.json serialization-config.json
  49. Copyright © Accso – Accelerated Solutions GmbH 58 Beispiel „reflection“:

    Java-Agent erzeugt JSON-Files lehmann@edwards03:~/graal/graalvm-native/reflection $ cat target/META-INF/native-image/reflect-config.json [ { "name":"StringManipulator", "methods":[ {"name":"capitalize","parameterTypes":["java.lang.String"] }, {"name":"reverse","parameterTypes":["java.lang.String"] } ] } ] Exception in thread "main" java.lang.NoSuchMethodException: StringManipulator.reverse(java.lang.String) at java.lang.Class.getDeclaredMethod(DynamicHub.java:2675) at ReflectionCaller.main(ReflectionCaller.java:10) Laufzeitfehler bei unzureichender Konfiguration
  50. Copyright © Accso – Accelerated Solutions GmbH 59 Beispiel „reflection“:

    Java-Agent erzeugt JSON-Files lehmann@edwards03:~/graal/graalvm-native/reflection $ cat target/META-INF/native-image/reflect-config.json [ { "name":"StringManipulator", "methods":[ {"name":"capitalize","parameterTypes":["java.lang.String"] }, {"name":"reverse","parameterTypes":["java.lang.String"] } ] } ] # create native-image (again) with explicit reflection configuration ${GRAALVM_HOME}/bin/native-image \ --no-fallback \ -H:+PrintAnalysisCallTree -H:+ReportExceptionStackTraces \ -H:ReflectionConfigurationResources=\ ./META-INF/native-image/reflect-config.json \ ReflectionCaller reflectionCallerWithExplicitConfiguration
  51. Copyright © Accso – Accelerated Solutions GmbH 60 Vorsicht Falle:

    Laufzeit-Fehler und -Fallback auf JVM build3_with-reflect-config.sh (gekuerzt) # create native-image with explicit reflection configuration ${GRAALVM_HOME}/bin/native-image \ --no-fallback \ -H:+PrintAnalysisCallTree -H:+ReportExceptionStackTraces \ -H:ReflectionConfigurationResources=\ ./META-INF/native-image/reflect-config.json \ ReflectionCaller reflectionCallerWithExplicitConfiguration Ohne „--no-fallback“ fällt das Native-Image bei Problemen zur Laufzeit automatisch auf eine installierte JVM zurück (aus $PATH bzw. $JAVA_HOME). → Für Reproduzierbarkeit den Fallback deaktivieren (vor allem, wenn man die Zielumgebung nicht komplett unter Kontrolle hat). Ohne „--no-fallback“ fällt das Native-Image bei Problemen zur Laufzeit automatisch auf eine installierte JVM zurück (aus $PATH bzw. $JAVA_HOME). → Für Reproduzierbarkeit den Fallback deaktivieren (vor allem, wenn man die Zielumgebung nicht komplett unter Kontrolle hat).
  52. Copyright © Accso – Accelerated Solutions GmbH 61 Spring Native

    – Spring Apps auf Graal/Native https://spring.io/blog/2020/04/16/spring-tips-the-graalvm-native-image-builder-feature
  53. Copyright © Accso – Accelerated Solutions GmbH 62 Test und

    einige Fallen Performance: Wie schnell ist das wirklich? Einführung: Graal? Native-Image! Fazit
  54. Copyright © Accso – Accelerated Solutions GmbH 63 GraalVM ist

    top, Native-Images noch nicht soweit?! Gut All-in-one-Sorglos-Binary- Paket mit „allem drin“. Startup-Zeiten sind sensationell schnell. Optimierter Speicherverbrauch Tool-Chain sehr stabil, z.B. auch Maven Selbst Polyglott integrierbar. Vieles funktioniert erwartungskonform (z.B. Exceptions, GC, …) Wird immer besser Schlecht Performance: Auf lange Sicht ist die JVM noch nicht zu schlagen. Build-Zeiten sind exorbitant. Nicht alles nutzbar, nicht alles stabil, manche Fehler sieht man erst zur Laufzeit. Sehr viele Varianten zur Optimierung Ungewohnt Monitoring und Fehlersuche zur Laufzeit ist … anders Man muss (oder darf) alt- bekannte Unix-Tools wie strings, file, strace, ltrace, ldd und gdb wieder auspacken. Debugging mit gbd (hier)? GraalVM ist ein hochspannendes Projekt und die Zukunft der Java-Plattform. Ob man schon heute Native-Images produktiv nutzen möchte, sollte man sich aber gut überlegen.
  55. Copyright © Accso – Accelerated Solutions GmbH 64 Fazit: Das

    ist die Zukunft?! https://mail.openjdk.java.net/pipermail/discuss/ 2020-April/005429.html https://www.youtube.com/watch? v=QUbA4tcYrTM
  56. Copyright © Accso – Accelerated Solutions GmbH 66 Copyright ©

    Accso GmbH https://speakerdeck.com/mrtnlhmnn https://github.com/accso/graalvm-native : @mrtnlhmnn @accso https://accso.de/ https://accso.de/publikationen/ 66 Accso – Accelerated Solutions GmbH +49 6151 13029-0 [email protected] www.accso.de Hilpertstraße 12 | 64295 Darmstadt Rahmhofstraße 2-4 | 60313 Frankfurt a.M. Im Mediapark 6a | 50670 Köln Balanstraße 55 | 81541 München