Java is one of the most well-known programming languages in the world, and is used in almost all fields. Industrial giants in finance, e-commerce, enterprise tech, and other fields rely on Java for complex tech products and services. It is arguably the most useful language in the tech industry now that its value is apparent in mobile, distributed, and big data applications.
One of the biggest features of Java has been its JIT compiler, a component that converted bytecode to native machine code Just In Time (JIT) to run the code.
However, as the demands of the tech industry have ramped up, JIT is no longer feasible. To that end, Java has released a brand new tool that works on the Ahead Of Time (AOT) principle. This tool, known as GraalVM, allows developers to write and compile code before execution. It consists of a Java Virtual Machine (JVM), and a Java Development Kit (JDK), as well, with a number of optimizations built in.
Introduction to GraalVM
So, what exactly is GraalVM?
Like most open-source projects, GraalVM comes with 2 types of distributions:
GraalVM Enterprise – Based on Oracle JDK
GraalVM Community – Based on OpenJDK
Both types support Java 11 and Java 17, as well as Windows, Linux, and MacOS x86 64-bit systems. At the time of writing, it also supports ARM 64-bit system.
Pic Courtesy: GraalVM.org
Features of GraalVM
- High Performance – GraalVM offers a number of performance improvements, including faster bootup of applications, leaner code, and reductions in memory and storage footprints.
- Polyglot Programming – GraalVM allows developers to mix multiple programming languages in a single application without any overhead of foreign language calls.
- AOT Native Image Compilation – GraalVM allows developers to convert Java applications to native, thanks to its advanced Ahead Of Time compiler.
- Advanced toolset – GraalVM also offers a broader toolset, including the Chrome DevTools Protocol, VS Code extensions, and Java extensions, all of which can be used for debugging, profiling, and monitoring.
What makes GraalVM highly performant?
The GraalVM Compiler works on the AOT (ahead-of-time) principle. It performs compilation during build time, long before execution. It also creates a native binary executable, making executing code easier and faster.
In JIT (just-in-time), the traditional approach of JRE, compilation and execution happen at the same time.
GraalVM performs a static analysis of the Java bytecode, and collects all the necessary code in use. It then converts the java bytecode of all the collected code into native binary, which can be executed in the binary format independent of JRE.
The binary code generated in this way is leaner, and takes less time to boot up since it does not need to warm up with unnecessary classes.
Who is using GraalVM?
Due to its diverse toolset and manifold advantages, industry leaders like Facebook, Oracle Cloud, Nvidia, Goldman Sachs, and Alibaba Group, are using GraalVM in various products and use cases.
Which Java frameworks support GraalVM?
In March 2021, Spring announced the launch of “Spring Native”. Spring Native provides support for compiling Spring applications using GraalVM. As of the current release of Spring Boot 2.6.7, Spring supports the compilation of Spring Boot Applications to native images using GraalVM too. However, Spring continues to support regular JVM as well. For more details, you can visit https://spring.io/blog/2021/03/11/announcing-spring-native-beta
Apart from Spring, Quarkus, Micronaut, Helidon & Gluon Substrate have also introduced support for GraalVM.
GraalVM In Action
In this section, we will demonstrate the creation of a Spring Boot Application. The goal of this section is to show how to generate a native binary executable step-by-step, as well as to set benchmarks for startup & memory usage.
- Download GraalVM JDK or Docker images and configure them. In this case, we will be using GraalVM CE 22.1.0 with Java 17
- Create a simple Spring Boot project with REST Controller on the “Spring Initializr” portal, using Lombak, Spring data JPA, Web, H2 database, and Spring Native. Alternatively, you can clone this Github repository – https://github.com/chavakula/spring-boot-native.git which contains the app to be tested.
Code in action:
- Go to the project folder & run this command. It takes approximately 2-5 minutes of build time
./mvnw -DskipTests=true -Pnative clean package
- This will generate a binary in the “Target” folder with the “artifactid” defined in pom.xml
- Run the executable binary. Ideally, it should start just like a Spring Boot App.
Native Binary: 0.439 seconds startup time & 13.4% of memory on 1GB RAM, 1 CPU Core VM
Standard JAR: 9.604 seconds startup time & 16.6% of memory on 1GB RAM, 1 CPU Core VM
From the above observations, it is clear that native binary startup is lightning fast, and shows improvements in memory usage as compared to traditional JAR based applications.
Native binary executables are ideal for containers and cloud deployments since they are small, start extremely fast, and use significantly less CPU and memory. They can even be deployed on “Scratch” container images, otherwise known as empty images.
All in all, GraalVM offers significant improvements over its predecessor, and offers a number of tools optimized for cloud-native applications. GraalVM is an excellent choice for building applications in the hottest industries right now, and as the flaws are ironed out, it is sure to become the JDK of choice for Java developers worldwide.
GraalVM Documentation on configuration: https://github.com/graalvm/graalvm-ce-builds/releases/tag/vm-22.1.0
Spring Native documentation: https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/