GraalVM — Byte Code to Bit Code
GraalVM & Micronauts — for Modern MicroServices, Serverless 2.x : Part1
Join the DZone community and get the full member experience.Join For Free
Early adopters for Cloud-Native (microservices, serverless) are now moving to its next wave called v2.x., leveraging the maturity, learnings, and identified shortfalls to design next-level stuff.
Let's recap few purposes of going cloud-native that we will relate here:
- Cost — Memory vs Runtime.
- Start-up & execution time (cold star in Serverless).
- Enable polyglot.
The current era of microservices is dominated by Java + other JVM based languages by large. Beside JVM’s super-rich ecosystem of libraries, frameworks, community support etc. few observation like thick memory footprint, cold startup & extended execution time, less polyglot support factored engineers for moving away from JVM platforms towards non-JVM stuff like nodeJs, Go-Lang, Python for cloud-native ecosystem.
GraalVM — An Oracle Labs initiative in collaboration with open source community supported by (VMWare, Red Hat, Microsoft, Twitter, Amazon and more.). To quote from their website :
It is a new universal virtual machine that supports a polyglot runtime environment and the ability to compile Java applications down to native machine code. GraalVM removes the isolation between programming languages and enables interoperability in a shared runtime.
Why the Community Is Enthusiastic About GraalVM
GraalVM — Accelerating Application Performance
GraalVM is a modern JVM build on Oracle Java SE, which can improve the performance of any application written in Java or JVM without any single line change in existing code. It reduces the response time of end-users. This in turn frees up CPU, memory consumption, and can be better utilized for more capacity and load handling.
GraalVM — Highly Optimized Compiler
The GraalVM compiler is highly optimized to enhance a pre-written or the new application with its 62 separate compiler optimization algorithms (called “Phases”), of which 27 are patented. Many JVM languages (e.g., Java, Scala, Kotlin) will see around a 30%–40% speedup using GraalVM when compared with Java SE-8.
GraalVM Native image supports JVM-based languages, e.g. Java, Scala, Kotlin etc.GraalVM native binary executables have incredibly fast load and execution time(since program initialisation can be done at build time and the application is already compiled) and much smaller footprint (since the JVM and JIT compiler don’t have to be distributed).
This is especially important during a cold start (e.g. serverless on demand start-up) as there is really no time to waste waiting for Spring Boot, JRE to configure itself. In this case, the system would already face a considerable backlog of events to process.
In case of GraalVM, it needs to know in advance which bytecode is going to be executed. Features like runtime dependency injection (on which Spring Boot relies heavily) will not work out of the box. Instead, a framework like Micronaut (which uses compile time dependency injection, proxy objects etc.) can be leveraged. In addition, the time it takes to create a native image is quite considerable. A typical compilation to a native image might take several minutes, so this step is one you would like to do e.g. during a nightly build.
One can build a native image directly with Maven using the
mvn packagecommand without running the
“Native-Image” code does not run on Java VM, but includes necessary components like memory management and thread scheduling from a different virtual machine, called “Substrate VM”. It is a native runtime component (like the deoptimizer, garbage collector, thread scheduling etc.). The resulting program has faster startup time and lowers runtime memory overhead compared to a Java VM.
GraalVM’s — ( Ahead of Time Compiler) AoT vs OpenJDK’s JIT
This just-in-time compilation allows to understand the workload over time and optimize the final code depending on its nature. That’s the reason why over time the JVM is considered more performant than native executables doing the same.
Features like reflection and proxies, heavily used by dependency injection centered frameworks such as Spring, pose a serious challenge for AoT compilation.
Hotspot JVM JIT is like Diesel engine vs Petrol engine (AoT)
Those relationships require to be manually declared in configuration to allow the compiler know about them — you guessed it — ahead of time.
Recently, two new JVM frameworks based onGraalVM with this approach in mind: Micronaut and Quarkus.
GraalVM — MicroService & Serverless — for CloudNaitve EcoSystem
Microservices and serverless architectures are being implemented or are part of the roadmap in most modern solution stacks. Given that Java is still the dominant language for business applications, the need for reducing startup time for Java is becoming more important. Serverless architectures are one such area that needs faster startup time along along with applications hosted on container platform.
Several projects have accepted GraalVM Native Image as a platform for their applications like Quarkus, Micronaut . Spring Framework recently announced the upcoming support for native images.
GraalVM — Execution and Start-up time
“Loading Time Affects Your Bottom Line”
GraalVM allows you to compile a program ahead of time into a native executable that runs with Substrate VM. Substrate VM is written in Java and compiled into the native executable. The resulting program has faster startup time and less runtime memory overhead compared to a Java VM.
We measured startup and memory footprint of a basic microservice build in Micronaut.
My GitHub Repo for Demo Apps build with Micronauts for benchmarking :
GraalVM Polyglot Runtime
“Truffle Language Implementation Framework”
pom.xml file as for using Truffle plugin :
Cloud-Native Microservices, Serverless - Design Decision
Sometimes good performance means good throughput, sometimes it means low memory usage, and sometimes it means a fast cold-start startup time.
GraalVM vs Hotspot VM ( OpenJDK) - A Trade-offs while selecting Native Image:
Benefits of “Native-image” aren’t for free — they come with a cost.
Obviously the native executable can only run on a single platform. Another limitation is caused by missing metadata during runtime. Since by default native image doesn’t retain information about classes and methods, hence one’s ability to perform reflection is limited. As there are many Java frameworks that rely on reflective access, getting them run on Native Image may require additional configuration.
Ref: Oracle White Paper of GraalVM.
Opinions expressed by DZone contributors are their own.