The new GraalVM Enterprise 21.3 release has a lot to offer, but the two biggest developments are breakthrough Native Image performance results and Java 17 support. This release marks the arrival of significant Native Image throughput improvements that makes adoption an even more attractive proposition for developers building microservices. While excellent performance is critical, there are some great new language features in the recently debuted JDK 17 LTS (long term support) release that developers are eager to use and we’re pleased to be shipping full support in GraalVM Enterprise 21.3. But Java 17 support is not limited to applications running on the JVM. You can also leverage all the latest Java 17 language features in applications compiled ahead-of-time with Native Image. There are many other improvements in this release, but let’s take a closer look at these the key highlights of GraalVM Enterprise 21.3, available as part of an Oracle Java SE Subscription.
GraalVM Enterprise focuses on support for Java LTS releases for production deployments. While non-LTS Java releases 12 through 16 previewed and released new features, GraalVM 21.3 with Java 17 support is the first time many of these features are available in a GraalVM Enterprise release. Fortunately, moving from Java 11 to Java 17 is straightforward so you can take advantage of the performance improvements in GraalVM Enterprise. If you’re developing new applications, you can start to leverage great new features like sealed classes, pattern matching for switch expressions, and (my personal favourite) records.
As teased above, there’s big GraalVM Enterprise Native Image performance news in the 21.3 release! Since its introduction, the goal of Native Image has been to make ahead-of-time (AOT) compilation as fast, or faster, than traditional just-in-time (JIT) compilation. The challenge being that while all optimization decisions must be made at build time for AOT compiled applications, JIT compiled code can be continuously optimized at runtime using performance profiling data. But with GraalVM Enterprise 21.3, thanks to improvements in profile guided optimization (PGO), in combination with the use of the Java G1 garbage collector, AOT compiled applications can run at speeds on par with OpenJDK on popular benchmarks, while still reducing memory usage.
In the first chart below, you can see performance relative to OpenJDK (taken as a baseline of 1) on a number of benchmarks. Results are for JDK 11 as 17 results are pending benchmark suite updates. Performance ratios are expect to be similar. As expected, GraalVM Enterprise with the Graal JIT compiler on the JVM is the performance leader. GraalVM Community Edition Native Image performs significantly slower than OpenJDK, but the real story here is the performance of GraalVM Enterprise Native Image with PGO and G1 GC compared to OpenJDK. On a broad set of benchmarks it delivers performance similar to OpenJDK with the C2 JIT compiler.
This means that if you're currently running your application on an OpenJDK distribution, by compiling your application into a platform native executable using GraalVM Enterprise Native Image you can achieve similar performance while enjoying advantages like immediate peak performance with no warmup, reduced attack surface area, lower memory usage, and smaller disk footprint—all of which are ideal properties for microservices and other containerized workloads.
In the next chart you can see maximum memory used (RSS) when running the same benchmarks. What's interesting is that GraalVM Enterprise Native Image requires just 39% of the memory required by the same workload run on OpenJDK, but GraalVM Enterprise Native Image with PGO and G1 GC requires about 78%. That's only a 22% reduction. The reason is a classic space/speed tradeoff. G1 can improve application performance sometimes at the expense of more memory. What this means is that you have options that let you optimize for throughput, memory usage, or an acceptable balance.
For small self contained Native Image generated executables, containers are an obvious deployment strategy. To support container usage, several GraalVM Enterprise container images are now available in the Oracle Container Registry to support both development and deployment use cases. There’s an `enterprise` image that includes the gu (Graal Updater) utility that’ll let you build images with whatever components and language support your application needs. If you’re building with Native Image there’s a `native-image-ee` container image that includes everything you need to generate native executables. You can also take advantage of a variety of Native Image linking options including fully dynamic, fully static, and mostly static (except libc) to generate an executable that’s ideal for deployment on your choice of container image. Whether you’re using one of the provided container images or customizing your own with gu, these images are an ideal way to incorporate GraalVM Enterprise into your build pipelines.
GraalVM Enterprise 21.3 includes many new features and improvements in areas ranging from application performance, to development and debugging tools, to new container images. For an overview of the new features in each of the GraalVM components checkout this blog from GraalVM Developer Advocate Alina Yurenko, or for details on all the changes in 21.3 you can find them in the release notes.
Shaun Smith leads product management of Oracle Lab's GraalVM.