• GraalVM Community Edition is based on OpenJDK version 1.8.0_252 and OpenJDK version 11.0.7.
  • Oracle GraalVM Enterprise Edition is based on Oracle JDK version 1.8.0_251 and Oracle JDK version 11.0.7. You can find Oracle JDK release notes for these versions at the Oracle Technology Network website.
  • Added support for compiling classes with irreducible loops in the bytecode. These often occur in Kotlin applications using coroutines with loops. The support both improves performance of such applications and enables their ahead-of-time compilation.
  • Added new TuneInlinerExploration option to increase or decrease the time spent exploring inlining opportunities. Tuning this option helps to achieve better peak performance or limit time to reach (potentially lower) peak performance which might improve overall speed of the program. This option is only a heuristic and should be tuned for a specific application. This is a GraalVM Enterprise feature.
  • Added support to optimize away some redundant clone operations. For example, in code patterns similar to the one below, the GraalVM compiler will avoid creating the array clone: new int[length].clone().length
  • Added support for visualizing libgraal memory usage in VisualVM:

  • The mitigation of the Intel Jump Conditional Code (JCC) Erratum is now only enabled for CPUs that need it.
  • Significantly improved performance for some benchmarks on JDK 11 due to fixes in the area of synchronization. The most notable improvement is Renaissance:reactors which shows approximately 50% better results.

Native Image

  • Improved scalability of the static analysis. The static analysis time was infeasible for some large applications. We added a new mechanism, called “saturated type flows”, to make the analysis faster. The new analysis is disabled by default for GraalVM 20.1, but we plan to enable it by default in a future release. We encourage all users to try it out using the image builder option -H:+RemoveSaturatedTypeFlows. According to our measurements the precision of the static analysis is comparable, but if you have an application where many more classes or methods are reachable with this option please create an issue on GitHub.
  • Added new option for the image generator to exit handlers on termination signals: --install-exit-handlers. This improves the user experience when running a native image in a Docker container as the init process, since Linux does not install a default signal handler for the process with id “1” and the native image is therefore not reacting to a shutdown request from Docker.
  • Improved support for soft references. Before 20.1, soft references (the Java SoftReference class) were cleared immediately at every GC like weak references. Now they are cleared based on a policy that takes the last access and the memory pressure into account.
  • Added survivor spaces to the GC. Disabled by default until a proper policy is implemented, see this GitHub issue for ideas and tasks around GC in native images.
  • Added generation of Dwarf debug information.
  • Improved support for timezones: information about all timezones is now included in every image, and the default timezone is correctly initialized at image startup and no longer fixed at image generation time.
  • Improved checking that the native compiler toolchain is correct, for example, whether the compiler version on Windows is correct. This avoids strange errors due to known incompatible compiler versions.

Many more compatibility improvements and bug fixes can be found on GitHub. For example, here is a list of fixed issues relevant for Spring framework support.


  • Enabled ECMAScript 2020 mode features by default.
  • Implemented several ECMAScript proposals, including Optional Chaining, Hashbang Grammar, FinalizationRegistry, private class methods, RegExp Match Indices, export * as ns from "mod", Intl.Locale, Intl.DisplayNames, Intl.DateTimeFormat dateStyle and timeStyle.
  • Added npx (npm package runner) utility into GraalVM distributions.
  • Removed the JOni RegExp-engine and the use-tregex option. TRegex engine is now the default regex engine.
  • Removed our SIMD.js implementation.

LLVM Runtime

  • Added a preliminary support for running C++ code in managed mode. This is a GraalVM Enterprise feature.
  • Updated musl libc to version 1.1.24. This is a GraalVM Enterprise feature.
  • Both libc++ and libc++abi are now shipped as bitcode libraries.
  • Improved C++ support, libsulong++ is loaded only if libc++ is loaded. The executables (ELF, Mach-O) compiled with the toolchain usually have a dependency on this library and will continue to work. Plain bitcode files, which do not allow specification of dependencies, may fail with an error similar to the following:
    Global variable ZNSt3_15ctypeIcE2idE is declared but not defined.

    This can be solved, for example, by specifying the dependency on the command line lli --lib libc++.so.1 ... on Linux or lli --lib libc++.1.dylib on macOS.

  • Changed module initialization order to be only based on the dependencies recorded in the ELF/Mach-O file (instead of looking at imported symbols). This might change the order in which plain bitcode files are initialized since they do not allow recording dependencies. If the initialization order is important, the suggested approach is to use ELF/Mach-O files. See the Toolchain documentation for more details.
  • Added support for on-stack-replacement of loops during bitcode execution, now it can compile long-running loops before the surrounding function is compiled.


  • Updated to Python 3.8.2.
  • Improved tuples with primitive elements performance.
  • Improved performance of sequences, sets, dicts, and list expressions.
  • Added support of cProfile and trace modules through the GraalVM CPU sampler and coverage, respectively.
  • Added support of NumPy on macOS.
  • Added support of setuptools-scm and pytz.timezone.
  • Added support of a new syntax for iterable unpacking from yield and return statements.
  • Fixed issues with inspection and printing of non-Python numbers in the Chrome debugger.
  • Fixed issues with AST sharing across different contexts when these contexts run concurrently on multiple threads.
  • Fixed passing non-ASCII strings to gethostbyname.
  • Improved Jython compatibility mode: treat Java null as identical to Python None when comparing with the is operator.
  • Improved Jython compatibility mode: isinstance now works with Java classes and objects.
  • Moved all GraalPython specific functions on sys or builtins to the _graalpython_ module.

To see a complete list of changes, please refer to the project changelog.


  • Preview of improved graphical support based on the graphics, grDevices, and JavaGD packages
    • Use --R.UseInternalGridGraphics=false to activate this feature.
    • Our custom grid package re-implementation, which is currently the default, will be first deprecated and then removed in future releases.
  • Included GCC runtime libraries for supported systems (Linux and macOS)
  • Removed GFortran as a requirement to run FastR.
  • The GFortran runtime libraries versions are 4.8.5 on Linux and 8.3.0 on macOS. When compiling additional R packages with Fortran code, one must use GFortran of the same or higher version.
    • There’s a known issue: the libgomp.1.dylib library is not distributed with FastR on MacOS. To workaround this issue: install GCC with the package manager of your choice, e.g., brew install gcc locate file libgomp.1.dylib. Variable $GOMPLIB will denote full path to this library and $R_HOMEthe path to R installation: $GRAALVM_HOME/jre/languages/R on JDK8 based builds $GRAALVM_HOME/languages/R on JDK11 based builds execute these two commands: install_name_tool -change /cm/shared/apps/gcc/8.3.0/lib/libgomp.1.dylib $GOMPLIB $R_HOME/lib/libRblas.dylib install_name_tool -change /cm/shared/apps/gcc/8.3.0/lib/libgomp.1.dylib $GOMPLIB $R_HOME/lib/libRlapack.dylib
  • GFortran is now the default Fortran compiler even in the LLVM toolchain configuration.
  • Added support for traceback() to show frames from other GraalVM languages and C/C++ when run in the LLVM mode (--R.BackEnd=llvm).
  • Improved interoperability with other languages: “@” and “$” can be used to access members of foreign polyglot objects.

A detailed list of the changes and bug fixes is available in the project changelog.


  • Added nightly builds, see the README for details.
  • ||= will not compile the right-hand-side if it is only executed once, to match the idiomatic lazy-initialization use-case (see the blog post).
  • Optimized performance of bundle install.
  • Added the --metrics-profile-require option to profile searching, parsing, translating and loading files.
  • Changed the C API type VALUE to be defined as unsigned long as on MRI. This enables using switch (VALUE) and other expressions which rely on VALUE being an integer type.
  • Removed deprecated Truffle::System.full_memory_barrier, Truffle::Primitive.logical_processors, and Truffle::AtomicReference.
  • Improved interoperability with other languages: hash keys are no longer reported as polyglot members.
  • Added Truffle::Interop.hash_keys_as_members to treat a Ruby Hash as a polyglot object with the Hash keys as members.

Other 56 bug fixes and 52 compatibility improvements, see a detailed changelog.


Chrome Inspector
  • Implemented the display of asynchronous stack traces in debugger, in Chrome Inspector and in exception traces.
Language Server Protocol
  • Improved stability of GraalVM Language Server and GraalVM VSCode Extensions.
  • Changed to start GraalVM Language Server in the native mode for better startup performance.
  • Stabilized support for LSP in R and Ruby.
  • Enabled VisualVM to monitor libgraal memory usage.
  • Implemented showing compiled and interpreter time in the GraalVM sampler.
  • Improved JFR viewer to display stack traces for JFR events.
Ideal Graph Visualizer
  • Added grouping of graph dumps by session:

  • Added an action to go to compiler classes.
  • Improved stability of IGV to no longer hang on some graph layout.
GraalVM Updater gu
  • Added support for wildcards when GraalVM Updater installs from a directory (-C).

Updates for Polyglot Embedders

  • Added Value.isMetaObject(), Value.getMetaQualifiedName(), Value.getMetaSimpleName() and Value.isMetaInstance(Object) to allow language agnostic access to meta-objects like classes or types.
  • The result of Value.getMetaObject() will always return meta-objects. It is recommended but not required to change uses of meta-objects to use Value.getMetaQualifiedName() instead of Value.toString() to return a type name.
  • Added OptionDescriptor.getDeprecationMessage returning the option deprecation reason. Added OptionDescriptor.Builder.deprecationMessage() to set the option deprecation reason.
  • Added Context.Builder.hostClassLoader to allow an embedder to specify a context ClassLoader for code execution.

More changes can be found in the GraalVM SDK changelog.

Updates for Language and Tool Implementers

  • engine.Mode is now a supported option and no longer experimental.
  • Added new meta-data APIs to InteropLibrary:
    • has/getLanguage(Object receiver) to access the original language of an object
    • has/getSourceLocation(Object receiver) to access the source location of an object (e.g., a function or classes)
    • has/toDisplayString(Object receiver, boolean allowsSideEffect) to produce a human-readable string
    • has/getMetaObject(Object receiver) to access the meta-object of an object
    • isMetaObject(Object receiver) to find out whether an object is a meta-object (e.g., Java class)
    • getMetaQualifiedName(Object receiver) to get the qualified name of a meta-object
    • getMetaSimpleName(Object receiver) to get the simple name of a the meta-object
    • isMetaInstance(Object receiver, Object instance) to check whether an object is an instance of a meta-object
  • Added TruffleLanguage.getLanguageView that allows to wrap values to add language specific information for primitive and foreign values.
  • Added TruffleLanguage.getScopedView that allows to wrap values to add scoping and visibility to language values.
  • Added TruffleInstrument.Env.getScopedView and TruffleInstrument.Env.getLanguageView to access language and scoped views from instruments.
  • Added TruffleInstrument.Env.getLanguageInfo to convert language classes to LanguageInfo.
  • Added @GenerateLibrary(dynamicDispatchEnabled = false) that allows to disable dynamic dispatch semantics for a library. The default is true.
  • Added ability to load external default exports for libraries using a service provider. See GenerateLibrary(defaultExportLookupEnabled = true).
  • Added @ExportLibrary(transitionLimit="3") that allows the accepts condition of exported libraries to transition from true to false for a library created for a receiver instance. This is, for example, useful to export messages for array strategies.
  • Added support for asynchronous stack traces for languages and tools to allow debuggers to show them.

To see a full list of changes to APIs, proceed to the GraalVM Truffle changelog.