Este documento presenta las principales características de GraalVM. GraalVM es una máquina virtual políglota que puede ejecutar programas en Java y otros lenguajes como JavaScript, Python y R. También permite compilar código Java a nativo, interoperabilidad entre lenguajes, y usar programas Java como librerías nativas en otros lenguajes. El documento describe nueve casos de uso clave de GraalVM como reemplazo del JDK, compilador en el JDK, Java nativo, VM políglota, interoperabilidad, VM para lenguajes nativos, depur
2. WHO WE ARE
Jorge Hidalgo @_deors
Senior Technology Architect
Accenture Technology Spain
Global Java Lead
Spain Advanced Technology Center
Custom Engineering & Architecture Lead
José María Gutiérrez @J_M_Gutierrez
Technology Architect
Accenture Technology Spain
Spain Advanced Technology Center
Architecture & DevOps Squad
INFINITE
POSSIBILITIES
3. TL;DR
Los materiales están adaptados del taller sobre GraalVM
que realizó Chris Seaton en Oracle Code One 2018
La presentación y los ejemplos están disponibles aquí:
https://www.slideshare.net/deors/malagajug-graalvm
https://github.com/deors/graal-vm
4. GRAALVM
GraalVM – https://graalvm.org/
• Nueva máquina virtual políglota... JVM y mucho más
• Escrita en Java
• Open source (community edition)
• Existe también una versión empresarial
• Múltiples casos de uso
• En esta sesión veremos todos los más habituales
5. GRAALVM
1. GraalVM como reemplazo del JDK
2. Graal como compilador en el JDK
3. Java nativo
4. VM políglota
5. Interoperabilidad entre lenguajes
6. VM para lenguajes nativos
7. Interfaz de depuración única
8. Interfaz de monitorización única
9. Uso de programas Java como librerías nativas
7. GRAALVM
1. GraalVM como reemplazo del JDK
• GraalVM puede utilizarse como una VM alternativa para
ejecutar programas de JVM
• 1.8 de momento, en breve para 11
• Es un reemplazo 1:1, incluidos los mismos modificadores
de línea de comandos
8. GRAALVM
1. GraalVM como reemplazo del JDK
• GraalVM tiene varios componentes; uno de ellos es el
compilador Graal que se ejecuta por encima de los
compiladores por defecto en JVM
• Está escrita en Java, por lo que es más fácil de mantener y
evolucionar
• En muchos casos los programas ejecutados tienen mejor
rendimiento que en JVM
9. GRAALVM
1. GraalVM como reemplazo del JDK
# añadir Graal al path
export PATH=~/graal-vm/graalvm-ce-1.0.0-rc8/Contents/Home/bin:$PATH
# prueba sencilla con un programa que cuenta palabras
cd ~/graal-vm/topten && javac TopTen.java
# ejecución con Graal (activado por defecto)
time java TopTen large.txt
# ejecución desactivando el compilador de Graal
time java -XX:-UseJVMCICompiler TopTen large.txt
10. GRAALVM
1. GraalVM como reemplazo del JDK
• En un programa sencillo, donde el código solo se ejecuta
una vez, las diferencias apreciables son pocas o nulas
• El JIT entra en acción con el tiempo, optimizando cómo los
bytecodes se traducen a código nativo en función de los
recursos de la máquina y del uso que se da a cada bloque
de código
• Usando GraalVM de forma continuada en el tiempo
podemos comprobar si aporta mejoras de rendimiento
11. GRAALVM
1. GraalVM como reemplazo del JDK
# otra prueba, operando con números complejos en gran cantidad
cd ~/graal-vm/value-types && mvn package
# ejecución con Graal (activado por defecto)
java -jar target/benchmarks.jar -prof gc
# ejecución desactivando el compilador de Graal
java -XX:-UseJVMCICompiler -jar target/benchmarks.jar -prof gc
13. GRAALVM
2. Graal como compilador en el JDK
• Graal, es decir el compilador de GraalVM, está también
incluido en el JDK 11
• No es la última versión, pero se irá actualizando en
próximas versiones del JDK
• Puede utilizarse como compilador activándolo con flags
experimentales de la JVM
14. GRAALVM
2. Graal como compilador en el JDK
# repetimos la prueba de contar palabras
# OpenJDK 11 con compilador estándar
time java TopTen large.txt
# con Graal sobre OpenJDK 11
time java -XX:+UnlockExperimentalVMOptions
-XX:+EnableJVMCI
-XX:+UseJVMCICompiler
TopTen large.txt Activa Graal JIT
en OpenJDK
No es necesario especificar Graal porque
es el único compilador que cumple con la
interfaz JVMCI en el modulepath/classpath
15. GRAALVM
2. Graal como compilador en el JDK
# repetimos la prueba de números complejos
# OpenJDK 11 con compilador estándar
java -jar target/benchmarks.jar -prof gc
# con Graal sobre OpenJDK 11
java -XX:+UnlockExperimentalVMOptions
-XX:+EnableJVMCI
-XX:+UseJVMCICompiler
-jar target/benchmarks.jar -prof gc
17. GRAALVM
3. Java nativo
• JVM tiene un consumo de recursos que aunque merece la
pena en procesos de larga duración como batch y
servidores, no la hace tan óptima para procesos cortos o
de feedback rápido (como una CLI)
• Graal puede usarse como compilador AOT y compilar a
nativo cualquier código JVM (bytecodes)
18. GRAALVM
3. Java nativo
# ejecutamos con GraalVM un programa sencillo y de corta duración
time java TopTen small.txt
# lo pre-compilamos a código nativo (no bytecodes were harmed!)
native-image TopTen
# ejecutamos el código pre-compilado
time ./topten small.txt
# sin dependencias con GraalVM o con OpenJDK
otool -L topten
20. GRAALVM
4. VM políglota
• GraalVM, además de dar soporte a los lenguajes JVM,
puede utilizarse para ejecutar programas JavaScript
• Dos intérpretes: una implementación propia y un intérprete
de Node.js
• Además, con la ayuda de extensiones, puede utilizarse
para ejecutar programas Ruby, Python y R
21. GRAALVM
4. VM políglota
# implementación propia de JavaScript
js --version
# implementación de Node.js
node --version
# incluye npm
npm --version
22. GRAALVM
4. VM políglota
# ejemplo de servicio con Node.js y Express
cd ~/graal-vm/hello-express
npm install express
node hello-express.js
23. GRAALVM
4. VM políglota
# añadimos otros lenguajes a GraalVM
gu install ruby && ruby --version
gu install python && graalpython --version
gu install R && R --version
# ver las extensiones disponibles
gu list
# recomendable regenerar las imágenes nativas para mejorar rendimiento
gu rebuild-images polyglot libpolyglot js llvm python ruby
25. GRAALVM
5. Interoperabilidad entre lenguajes
• Además de ser políglota, GraalVM permite la
interoperabilidad entre los distintos lenguajes soportados
• Cada intérprete genera bytecodes que GraalVM ejecuta
independientemente del lenguaje de origen
• El mismo JIT y el mismo framework para el intérprete
26. GRAALVM
5. Interoperabilidad entre lenguajes
# ejemplo de programa Ruby llamando a Java
cd ~/graal-vm/interop
ruby --jvm ruby-java.rb
# ejemplo de programa Python llamando a Java
graalpython --jvm python-java.rb
El flag --jvm activa la
interoperabilidad
28. GRAALVM
5. Interoperabilidad entre lenguajes
# ejemplo de programa Node.js llamando a R
cd ~/graal-vm/cloudplot
npm install express
node --jvm cloudplot.js
# abrir en un browser
http://localhost:8080
http://localhost:8080/js
30. GRAALVM
6. VM para lenguajes nativos
• GraalVM también tiene un intérprete de LLVM
• Esto permite ejecutar en JVM cualquier lenguaje con un
compilador que emita LLVM
• Por ejemplo: C, C++, Objective C, Swift, Fortran, Rust y
otros
31. GRAALVM
6. VM para lenguajes nativos
# compilamos un programa C de forma normal y emitiendo LLVM
cd ~/graal-vm/gzip
clang gzip.c -o gzip
clang -c –emit-llvm gzip.c
# ejecutamos el programa nativo
time ./gzip large.txt && time ./gzip -d large.txt.gz
# ejecutamos el programa con el intérprete desde GraalVM
time lli gzip.bc large.txt && time lli gzip.bc -d large.txt.gz
33. GRAALVM
7. Interfaz de depuración única
• Una consecuencia de tener aplicaciones en múltiples
lenguajes ejecutándose en el mismo framework es poder
utilizar la misma interfaz de depuración
• Aplica a programas interoperando múltiples lenguajes
• Muy útil porque no todos los lenguajes tienen
depuradores, o no tienen depuradores con funcionalidad
tan rica como acostumbramos en JVM
34. GRAALVM
7. Interfaz de depuración única
# depuramos un programa Ruby
cd ~/graal-vm/fizzbuzz
ruby --inspect fizzbuzz.rb
# depuramos un programa Python
graalpython --inspect fizzbuzz.py
# depuramos un programa R
R --inspect -f fizzbuzz.r
36. GRAALVM
8. Interfaz de monitorización única
• En JVM estamos acostumbrados a usar herramientas como
VisualVM o Mission Control o JProfiler para monitorizar una
aplicación y obtener métricas JMX
• Con GraalVM podemos utilizar esas mismas herramientas
en cualquier lenguaje que soporta
• Muy útil porque no todos los lenguajes tienen herramientas
de monitorización o no son lo suficientemente ricas en
funcionalidad
39. GRAALVM
9. Uso de programas Java como librerías nativas
• Hemos visto que con GraalVM podemos ejecutar
programas en un amplio grupo de lenguajes
• Podemos interoperar con todos esos lenguajes
• Podemos convertir a nativo cualquier programa en Graal
• También es posible ejecutar programas Java desde un
programa nativo o con interfaz FF como Ruby, Python,
Rust, Go, Haskell, etc.
40. GRAALVM
9. Uso de programas Java como librerías nativas
• Como grandes ventajas:
• Elaboración automática de las interfaces
• API muy sencilla
• Compilado de la librería
• JNI... ¡Muchísimo más fácil que usar JNI!
41. GRAALVM
9. Uso de programas Java como librerías nativas
# programa para cálculo de distancias con Apache SIS
cd ~/graal-vm/distance
javac -cp sis.jar Distance.java
java -cp sis.jar:. Distance 51.507222 -0.1275 40.7127 -74.0059
# lo convertimos a programa nativo
native-image -cp sis.jar:. Distance
./distance 51.507222 -0.1275 40.7127 -74.0059
43. GRAALVM
9. Uso de programas Java como librerías nativas
# generamos la librería nativa del mismo programa
native-image -cp sis.jar:. -H:Kind=SHARED_LIBRARY -H:Name=libdistance
# las interfaces y la librería se generan automáticamente
ls -l libdistance*
# usamos la librería (¡Java!) desde un nuevo programa C
clang -I. -L. -ldistance distance.c -o distancec
otool -L distancec
./distancec 51.507222 -0.1275 40.7127 -74.0059
44. CONCLUSIONES
GraalVM – https://graalvm.org/
• Libertad en la elección de lenguaje
• Acceso a múltiples ecosistemas de librerías
• Ejecutando sobre JVM o nativo
• Interoperabilidad entre lenguajes
• Herramientas de monitorización y depuración
• Con mejor rendimiento
• ‘ONE COMPILER TO RULE THEM ALL’ ☺