22.2.0 #


Platform Updates #

  • Improved GraalVM packaging experience by reducing the size of the base binary almost ~2x. JavaScript, LLVM runtimes, and VisualVM are now decoupled from the main package and released as separate installable components. The package size of, for example, the GraalVM Community Linux distribution dropped from ~430 MB to ~250 MB. This makes GraalVM more modular offering the same RPM-like experience when you add support for only what you need.
  • The Native Image component size has increased because necessary runtime components (Substrate VM) and static libraries (used by Substrate VM) are now part of the Native Image installable.
  • Improved Apple Silicon support:
    • Released GraalVM Enterprise distribution for Apple Silicon (AArch64 architecture). The support is experimental.
    • Extended the supported GraalVM functionalities in the existing GraalVM Community distribution for Apple Silicon. You can now optionally install Native Image, the LLVM toolchain, Java on Truffle, and language runtimes for JavaScript, Ruby, WebAssembly.
  • GraalVM will no longer run on some older Linux AMD64 distributions. It is now built against glibc 2.17 (instead of 2.12), and as a result it may not run on Oracle Linux 6 or other RHEL 6 derivatives.

  • Updated the OpenJDK release on which GraalVM Community Edition is built to:
  • Updated the Oracle JDK release on which GraalVM Enterprise Edition is built to:

Java and Compiler Updates #

  • Improved the RSS memory usage by the JIT compiler (Graal) in GraalVM Community Edition. The memory used by libgraal is now reclaimed when compilation goes idle. It reduces RSS usage of JIT in a stable state (few or no compilations happening). To measure RSS memory usage of a Java process, you can run ps aux --sort -rss. See JDK-8242440.

  • Enhanced the Novel Strip Mining optimization for counted loops. The optimization can be enabled with this option: -Dgraal.StripMineCountedLoops=true. Strip Mining optimization converts a single long running loop into a nested loop where the inner body runs for a bounded time. It allows you to put a safepoint in the outer loop to reduce the overhead of safepoint polling. By choosing the right value for the outer loop stride, you still ensure reasonable time-to-safepoint latency. The latter is particularly important for low pause time collectors such as ZGC and Shenandoah. For example, this loop:

      int checksum = 0;
              for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
                  checksum += i;
                  // safepoint_poll

    would become:

      int checksum = 0;
      for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE - 1000; i += 1000) {
          for (int j = i; j < i + 1000; j++) {
              checksum += j;
          // safepoint_poll
      for (int i = Integer.MAX_VALUE - 1000; i < Integer.MAX_VALUE; i++) {
          checksum += i;
          // safepoint_poll

    This optimization adds to Truffle guest language safepoints latency. For example, Novel Strip Mining optimization eliminates HotSpot safepoints from a counted loop that does allocation (the HotSpot allocation slow path has a safepoint). However, this allocation related safepoint will not trigger a Truffle safepoint. As such, the Truffle safepoint latency can be very long. In this case, Novel Strip Mining optimization can decompose such a loop into strips and issue a Truffle safepoint poll once per strip.

  • Enabled floating and global value numbering of division nodes early on in the compilation pipeline if it is known they will not trap. This means division-by-constant operations can be commoned and moved out of loops if the constant divisor proves that they cannot throw div-by-zero exceptions. See #3866.

  • Introduced a global value numbering optimization for fixed nodes early in the compilation pipeline. Disabled by default, but can be enabled with -Dgraal.EarlyGVN=true. This optimization improve workloads that require complex partial escape analysis and unrolling optimizations in order to optimize away constant loops with complex object allocations. This optimization can also speed up Native Image build time (by reducing graph sizes earlier in the compilation pipeline) as well as speeding up the generated native executables themselves by folding more memory operations.

Native Image #

  • Enhanced the compatibility of GraalVM Native Image with the 3rd party libraries. The Oracle GraalVM team in conjunction with the Spring, Micronaut, and Quarkus teams have created a GitHub repository, GraalVM Reachability Metadata Repository, a centralized place that provides configuration (reachability metadata) for libraries which do not support GraalVM Native Image by default. The support needs to be enabled explicitly. For example, in Gradle you can enable this repository with:
      graalvmNative {
          metadataRepository {
              enabled = true

    The GraalVM Reachability Metadata Repository enables users to share and reuse reachability metadata for the most popular libraries in the Java ecosystem. Check the documentation for more informaition.

  • The native-image generator now runs on the module path by default. This is part of a longer-term effort to support module-based applications using a clean module-based generator. The module system prevents direct access to internals of the native-image generator by default. Applications and frameworks can still provide command-line arguments to open up the internals again using the usual module system command line options. For now, the old mode of running the native-image generator can be enabled by setting the environment variable USE_NATIVE_IMAGE_JAVA_PLATFORM_MODULE_SYSTEM=false (but note that this mode will be deleted without replacement in a future release).

  • Improved many internal data structures of the native-image generator to reduce the memory footprint. This makes Native Image builds more robust when running on memory-constraint environments like cloud-based build services, GitHub Actions, or in Docker containers. Many larger application now build successfully with 2 GByte of Java heap size available for the native-image generator.

  • Added support for Software Bill of Materials (SBOM). The native-image generator can optionally include a SBOM into a native executable to aid vulnerability scanners. Currently, the CycloneDX format is supported. Users may embed a CycloneDX SBOM into a native executable by using the -H:IncludeSBOM=cyclonedx option during compilation. After embedding the compressed SBOM into the executable, you can use the Native Image Inspect tool to extract the compressed SBOM with this command: $JAVA_HOME/bin/native-image-inspect --sbom <path_to_binary>. Check the documentation for more details. GraalVM Enterprise only

  • Added a new optimization for String concatenation operations (including StringBuilder operations): it eliminates temporary memory buffers during concatenation. GraalVM Enterprise only

  • Heap dumps at image run time are now supported in GraalVM Community Edition. Also, a new runtime option, -XX:+DumpHeapAndExit, has been introduced to dump the initial image heap of a native executable. Check the documentation how to dump the initial heap of a native executable.

  • Improved debugging support on Linux: The Dwarf information now contains information about parameters and local variables (contributed by Red Hat).

  • Certain Native Image options can now only be provided on the command-line and no longer in native-image.properties files. These options also get processed before other options so that they properly pre-configure all other options coming from both the command line and native-image.properties files. The affected options are --exclude-config, --configurations-path, --debug-attach, --diagnostics-mode, as well as all the options to print help messages.

  • Added a new runtime option -XX:+ExitOnOutOfMemoryError that aborts the execution of a native executable on the first out-of-memory error.

  • Added support for most methods of OperatingSystemMXBean at image run time.

  • Annotation classes are no longer force-initialized at image build time. Like any other class, annotation classes can now be initialized either at build time or at run time using the according command-line options (--initialize-at-build-time or --initialize-at-run-time) or the Feature API. This fixes problems with transitive dependencies of annotations, including non-annotation classes that are used by annotations. See Class Initialization in Native Image.

Polyglot Runtime #

  • Introduced updates that improve interpreter-only performance for 20-30% and warmup for GraalVM supported languages.
  • Added support in libgraal for caching encoded graphs across Truffle compilations to speedup partial evaluation. The cache is enabled by default and can be enabled/disabled with the --engine.EncodedGraphCache option. This update contribute to faster compilation time improvements on HotSpot.
  • Implemented a new domain specific inlining phase for the Truffle interpreter host compilation, which improves the interpreter performance for GraalVM Native Image. See the Host Compilation for Interpreter Java code reference manual for details.

A full list of updates can be found in the changelog.

JavaScript #

  • JavaScript support is now decoupled from the base GraalVM installation and can be easily added with this command: gu install js.
  • Improved JavaScript interoperability with Java: now foreign objects get a JavaScript prototype assigned by default, unless explicitly turned off. This feature was available behind the experimental option js.foreign-object-prototype before and now made default. Previously, if you use any foreign object like a Java array in JavaScript code, you could access it by using the index operator []. The array did however lack the Array.prototype, and thus methods like indexOf or sort could not be easily called on it. With this change, foreign objects get a fitting JavaScript prototype assigned and can be “manipulated” with regular JavaScript functions. This adds more flexibility for regular Java or GraalVM Polyglot API users.
  • Extended the implementation of the Temporal specification in GraalVM JavaScript, which provides standard objects and functions for working with dates and times. Changes from the specification are adopted continuously. Temporal objects can now be converted to compatible Java objects when appropriate, using the Value API’s methods like asDate(). The opposite direction, providing Java Temporal objects and using them with JavaScript Temporal methods is planned for a future release.

See the project changelog.

Ruby #

  • Added support for AArch64 distribution for macOS (Apple Silicon).
  • Added support for OpenSSL 3.0.0 by updating the openssl gem.
  • Updated to Ruby 3.0.3. The 3 CVEs did not affect TruffleRuby, this is to bring the stdlib and gem update.
  • Implemented several changes that improve Ruby performance on GraalVM:
    • Reimplemented Float#to_s for better performance.
    • Updated reference processing by making C object free functions and other finalizers more lightweight.
    • Improved performance of RSTRING_PTR for interned strings.
    • Enabled caching constant argument formats used with rb_scan_args_kw.
  • Improved compatibility with CRuby 3.2: -Werror=implicit-function-declaration is now used for compiling C extensions to fail more clearly and earlier if a function is missing.

A full list of changes is available in the changelog.

Python #

  • Updated to HPy version 0.0.4, which adds support for the finished HPy port of Kiwi, and the in-progress ports of Matplotlib and NumPy.
  • Added an experimental bytecode interpreter for faster startup and better interpreter performance. Using either the previous AST interpreter or the new bytecode interpreter can be switched using the --python.EnableBytecodeInterpreter option.

The project changelog is available on GitHub.

R #

  • Implemented SET_GROWABLE_BIT and IS_GROWABLE C API functions. This fixes installation of the cpp11 0.2.6 package.
  • Added akima package to the list of “native packages”, so it is by default loaded by the native backend.

The project changelog is available on GitHub.

LLVM Runtime #

  • The LLVM runtime is now decoupled from the base GraalVM installation and can be easily added with this command: gu install llvm.
  • Updated LLVM toolchain to version 14.0.3.
  • Added support for AArch64 distribution for macOS (Apple Silicon).
  • Improved support for POSIX Threads, pthreads, managed execution mode. In mode does not allow to call native code and access native memory.

Java on Truffle #

  • Added support for AArch64 distribution for macOS (Apple Silicon).
  • Improved class redefinition: added support appending enum constants. This makes HotSwap capabilites more powerful while changing classes at runtime during a debugging session. See the Enhanced HotSwap Capabilities with Java on Truffle guide.
  • Enable the new Class Hierarchy Analysis by default. It provides information about class hierarchy in the guest code, evolving as new classes are loaded.

WebAssembly #

  • This release is marked by significant performance improvements in GraalVM WebAssembly implementation based on our benchmarks:
    • Internal AST memory footprint improvements 3.18x
    • Peak performance improvements 1.24xs

Polyglot Embedding #

  • Added the ability to spawn a native-image isolate for each Engine or Context in a native launcher or library. This feature was previously supported only for the JVM deployment. GraalVM Enterprise only
  • Added Value.hasMetaParents() and Value.getMetaParents() methods that allow lookup of the hierarchy of parents for meta objects (for example, a super class or implemented interface of Java classes).
  • Added HostAccess.Builder.allowAccessInheritance to inherit access to methods that have been explicitly exported in an interface or superclass versus only explicitly vetted method implementations (for example, via @HostAccess.Export).
  • Added List#add support for polyglot values that are mapped to java.util.List.

A full list of changes is available in the changelog.

Truffle Language and Tool Implementations #

  • Added new static APIs to com.oracle.truffle.api.frame.Frame:
    • Implemented a new static option to FrameSlotKind for index-based slots. Frame slots using this kind cannot be changed to another kind later on. Static frame slots can simultaneously hold one primitive and one object value. Static frame slots are intended for situations where the type of a variable in frame slots is known ahead of time and does not need any type checks (for example, in statically typed languages).
    • Static frame slots are intended for situations where the type of a variable in a frame slots is known ahead-of-time and does not need any type checks (for example, in statically typed languages).
  • The Static Object Model offers preliminary support for field-based storage also for GraalVM Native Image.
  • Truffle IGV dumping with log level 5 (-Dgraal.Dump=Truffle:5) now dumps the graph after each method that was fully partially evaluated. This enables debugging of problems only visible during partial evaluation.

A full list of updates can be found in the changelog.

Tools #

  • Improved building native images on Windows with our GraalVM for Java VS Code Extension. Now, .\gradlew nativeBuild on Windows 10 runs inside x64 Native Tools Command Prompt.
  • GraalVM Updater can now produce JSON output for the available, list, and info commands, which makes it easier for other tools such as the GraalVM for Java VS Code Extension to programmatically use it.

Connect with us