Fundamentals 18 min read

GraalVM 21.2 Highlights: Native Image, Compiler, and Multi‑Language Improvements

GraalVM 21.2 introduces major updates across its ecosystem, including new Gradle and Maven plugins for Native Image with JUnit 5 support, enhanced compiler optimizations, expanded Truffle language capabilities, improved JavaScript, Ruby, Python, LLVM, and upgraded tooling such as VisualVM and JFR integration.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
GraalVM 21.2 Highlights: Native Image, Compiler, and Multi‑Language Improvements

Introduction

GraalVM 21.2 has been released. This article highlights the most visible, important, and exciting updates in this version.

GraalVM can be downloaded from the official GraalVM page and the GraalVM Enterprise page. For detailed component changes, refer to the documentation.

Native Image

New Gradle and Maven plugins for Native Image were released in June, along with initial JUnit 5 support, simplifying the build process and allowing tests to run in Native Image mode.

Two minor releases have fixed bugs and improved stability; users of Native Image should run the two tests to verify behavior.

Native Image now automatically removes unnecessary security providers. Parameters like

--enable-all-security-services

are deprecated; use

-H:-EnableSecurityServicesFeature

to disable automatic detection and manually register providers.

Class predefinition support enables runtime

ClassLoader.loadClass

calls. Classes required at runtime must be provided during build for static analysis, allowing dynamic class loading in native images.

The

-H:+AllowVMInspection

flag now enables Java‑written JFR events. Use

-XX:+FlightRecorder

and

-XX:StartFlightRecording

to record events.

Example of a custom JFR event:

<code>import jdk.jfr.Event;
import jdk.jfr.Description;
import jdk.jfr.Label;

public class Example {
    @Label("Hello World")
    @Description("Helps programmer getting started")
    static class HelloWorld extends Event {
        @Label("Message")
        String message;
    }

    public static void main(String... args) {
        HelloWorld event = new HelloWorld();
        event.message = "hello, world!";
        event.commit();
    }
}
</code>

Build it into a native image with

-XX:+FlightRecorder -XX:StartFlightRecording="filename=recording.jfr"

and view the event in VisualVM.

Compiler Updates

Incremental improvements and new optimizations increase performance. Notable enhancements include loop limit analysis, strip‑mine non‑counted loops (

-Dgraal.StripMineNonCountedLoops=true

), StringBuilder pattern support, speculative guard movement, and safe‑point elimination for long‑type loops.

<code>long i = 0;
if (end < 1) return;
do {
    // body
    i++;
} while (i != end);
</code>

The compiler can now prove that

i

stays within integer range for long loops, eliminating overflow checks.

Experimental optimizations such as Write Sinking (

-Dgraal.OptWriteMotion=true

) and SIMD vectorization (

-Dgraal.VectorizeSIMD=true

) are available but disabled by default.

Multi‑Language and Truffle Framework

A new compilation‑queue heuristic improves warm‑up time for all GraalVM languages. Configuration options allow tuning or disabling the heuristic.

Embedding multi‑language contexts now requires a newer JVMCI version (JDK‑8264016) for full compatibility.

Truffle libraries can now be prepared for ahead‑of‑time compilation without prior execution. See

ExportLibrary.useForAOT

and the AOT tutorial for details.

JavaScript

Graal.js adds implementations for the new Set methods proposal, experimental operator‑overloading support, and RegExp match‑index proposal. The

js.unhandled-rejections

option can be set to track unhandled promise rejections.

Ruby

Ruby receives continuous compatibility and performance improvements, including precise method and constant invalidation based on assumptions, and a new

TruffleRuby::ConcurrentMap

data structure. Ruby 2.7.3 is now bundled, though

resolv

has a known bug.

Python

A faster

_pickle

implementation improves serialization speed. Interoperability with other languages is enhanced, and

dict

now uses the Truffle hash implementation.

LLVM Bitcode Runtime

Fixes for LLVM toolchain on macOS 11.3 and added support for C virtual calls improve cross‑language interoperability.

In GraalVM Enterprise, the managed mode updates musl libc to 1.2.2 and adds support for

pthreads

and

pthread

synchronization primitives.

FastR

FastR improves CRAN snapshot compatibility, adding support for R packages such as tibble 3.0.6, vctrs 0.3.6, data.table 1.13.6, and ongoing work for dplyr, ggplot, and knitr.

WebAssembly

Numerous compatibility improvements and bug fixes enhance the WebAssembly runtime, covering many NPM modules.

Java on Truffle

A new Hotswap plugin API allows code reloading without restarting the application, enabling frameworks to react to IDE edits via registered listeners.

Bytecode scheduling improvements boost interpreter speed by 15‑30 %, and implementations for

Map

,

Map.Entry

,

List

,

Iterator

, and

Iterable

improve inter‑language interoperability.

Tools

VisualVM gains many enhancements, including JDK 17 support, command‑line control, seamless VS Code integration, the ability to save JFR recordings from live Java processes, and a new Lock Contention view.

Documentation

The GraalVM website documentation has been restructured and is now hosted on the main GitHub project. Contributions are encouraged via pull requests, and the Enterprise documentation is available on docs.oracle.com.

References

Release notes: https://www.graalvm.org/release-notes/21_2/

Gradle and Maven plugins for Native Image: https://medium.com/graalvm/gradle-and-maven-plugins-for-native-image-with-initial-junit-testing-support-dde00a8caf0b

Native Image security services documentation: https://www.graalvm.org/reference-manual/native-image/JCASecurityServices/

Java JFR event API: https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jfr/jdk/jfr/Event.html

Truffle compilation queue heuristic: https://github.com/oracle/graal/blob/master/truffle/docs/TraversingCompilationQueue.md

ExportLibrary.useForAOT: https://www.graalvm.org/truffle/javadoc/com/oracle/truffle/api/library/ExportLibrary.html#useForAOT--

AOT tutorial: https://github.com/oracle/graal/blob/master/docs/graalvm-as-a-platform/truffle-framework/AOT.md#truffle-aot-tutorial

New Set methods proposal: https://github.com/tc39/proposal-set-methods

Operator overloading support: https://github.com/oracle/graaljs/blob/master/docs/user/OperatorOverloading.md

Ruby bug 17748: https://bugs.ruby-lang.org/issues/17748

Ruby release notes: https://github.com/oracle/truffleruby/releases/tag/vm-21.2.0

Managed mode limitations: https://www.graalvm.org/reference-manual/llvm/NativeExecution/#limitations-and-differences-to-managed-execution-on-top-of-graalvm-enterprise

Hotswap plugin API: https://www.graalvm.org/reference-manual/java-on-truffle/hotswap-plugin/

GraalVM GitHub docs: https://github.com/oracle/graal/tree/master/docs

Contributing to docs: https://github.com/oracle/graal/tree/master/docs#readme

Oracle GraalVM docs: https://docs.oracle.com/en/graalvm/index.html

GraalVMnative-imageTruffleMulti-languageCompiler Optimizations
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.