Graal VM
Graal VM
eazy
bytes
GraalVM is a high performance JDK that speeds up the performance of Java and JVM-based applications and simplifies the
building and running of Java cloud native services. The optimized compiler generates faster code and uses fewer compute
resources, enabling applications to start instantly.
GraalVM, built on trusted Oracle Java SE, solves the challenges of cloud-native
application development by providing a state-of-the-art JIT compiler that
accelerates application performance, lowers required memory per operation, and
reduces operating costs.
In simple words, GraalVM enhances the Java ecosystem by offering a compatible and
better-performing Java Development Kit (JDK).
eazy
What happens inside normal JDKs ? bytes
JVM
What happens inside JVM ?
Class Loading: The JVM starts by loading the necessary classes and resources required by the Java program. It searches for bytecode files
(.class) that correspond to the classes used in the program and loads them into memory.
Bytecode Verification: Once the classes are loaded, the JVM performs bytecode verification. It checks the bytecode for any violations of
the Java language specification, such as illegal type casts or access to private fields. This step ensures the safety and security of the JVM
by preventing the execution of malicious or malformed bytecode.
Just-In-Time (JIT) Compilation : After the bytecode is verified, the JVM employs a Just-In-Time (JIT) compiler to convert the bytecode into
machine code. The JIT compiler analyzes the bytecode and identifies portions of the code that are frequently executed, known as hot
spots. It optimizes these hot spots by translating them into highly optimized machine code, specific to the underlying hardware and
operating system. This compilation process is known as dynamic or on-the-fly compilation because it happens during runtime.
Execution: Once the JIT compilation is complete, the JVM starts executing the optimized machine code. It interprets the bytecode and
executes the corresponding native instructions. At this stage, the Java program is running natively on the underlying hardware, similar to
programs written in other programming languages.
eazy
What happens with GraalVM bytes
JIT mode
javac Hello.java java Hello output
JIT
AOT mode
output
native-image Hello ./hello
javac Hello.java
JDK
Substrate VM
Any dynamic code invoked with Java reflections, JNI,
Dynamic proxy etc. can’t be analysed by GraalVM since it
performs static analysis. To over come this, we need to
provide Reachability Metadata to GraalVM
AOT
Load native executable Initiate the start
code from disk process with full speed
Since the number of steps with GraalVM is less and code is ready for execution in
the native format, the start time will be less compared to traditional JDKs.
Verify class
JIT Initiate the start
Load JAR files process with full
from disk definitions profiling
speed
Application
Dynamic code cache
machine code
Runtime VM &
Compiler Application payload
Compact packaging
Profiling feedback
Class metadata
definition Since the number of activities at run
time by AOT are less, it will consume less
Application payload
memory compared to JIT
Polyglot support GraalVM provides support all JVM languages like Java Kotlin, Scala,
Groovy, non JVM languages like Python, R, Ruby, JavaScript and LLVM
languages like C, C++.
GraalVM static analysis may not automatically detect all your reflection code,
JNI, Dynamic proxy code. Workaround is to provide this information manually to
the GraalVM using Reachability metadata
Maintining Reachability metadata for our own application code is fine, but how
about the dynamic code used in libraries, frameworks ?
The solution is https://github.com/oracle/graalvm-reachability-metadata , to
share and reuse metadata for libraries and frameworks in the Java ecosystem.
Apart from this, major frameworks like Spring Boot, Quarkus, Micronaut,
Helidon are already updated their code to provide this Reachability metadata.
Duing local development and unit testing, it will be annoying to use AOT
because it takes lot of time to generate native executable code. Instead
use JIT and go for AOT only during the final build process