- GraalVM Release Calendar
- GraalVM for JDK 24
- GraalVM for JDK 23
- GraalVM for JDK 22
- GraalVM for JDK 21
- GraalVM for JDK 20
- GraalVM for JDK 17
- GraalVM 22.3.x
- GraalVM 22.2.x
- GraalVM 22.1.x
- GraalVM 22.0.x
- GraalVM 21.3.x
- GraalVM 21.2.x
- GraalVM 21.1.x
- GraalVM 21.0.x
- GraalVM 20.3.x
- GraalVM 20.2.x
- GraalVM 20.1.x
- GraalVM 20.0.x
- GraalVM 19.3.x
Oracle GraalVM for JDK 24
(2025-03-18)
- Platform and Distributions
- Availability of JDK 24 Features
- Graal Compiler
- Native Image
- Polyglot Runtime
- GraalJS
- GraalPy
- GraalWasm
- Espresso
- TruffleRuby
- Truffle Language Implementation Framework
Platform and Distributions
- Released Oracle GraalVM for JDK 24 based on Oracle JDK 24. See Java SE 24 Release Notes.
- Released GraalVM Community Edition for JDK 24 based on OpenJDK 24. See OpenJDK 24 Updates.
- Version compatibility:
- GraalVM for JDK 24 is compatible with Graal Languages and other components version 24.2.0.
Features
- 450: Compact Object Headers (Experimental)
- 472: Prepare to Restrict the Use of JNI
- 475: Late Barrier Expansion for G1
- 478: Key Derivation Function API (Preview)
- 479: Remove the Windows 32-bit x86
- 484: Class-File API
- 485: Stream Gatherers
- 486: Permanently Disable the Security Manager
- 487: Scoped Values (Fourth Preview)
- 488: Primitive Types in Patterns, instanceof, and switch (Second Preview)
- 489: Vector API (Ninth Incubator)
- 490: ZGC: Remove the Non-Generational Mode
- 491: Synchronize Virtual Threads without Pinning
- 492: Flexible Constructor Bodies (Third Preview)
- 493: Linking Run-Time Images without JMODs
- 494: Module Import Declarations (Second Preview)
- 495: Simple Source Files and Instance Main Methods (Fourth Preview)
- 496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism
- 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm
- 498: Warn upon Use of Memory-Access Methods in sun.misc.Unsafe
- 499: Structured Concurrency (Fourth Preview)
- 501: Deprecate the 32-bit x86 Port for Removal
Graal Compiler
- The default number of JVMCI threads is now the same as of C2 threads (
-XX:JVMCINativeLibraryThreadFraction=0.66
). This benefits program warmup but could increase the maximum RSS. Setting-XX:JVMCINativeLibraryThreadFraction
to a smaller value will result in smaller maximum RSS but potentially longer warmup. (See JDK-8337493.) - Display a deprecation warning upon the first use of the legacy
graal.
prefix. This warning will be upgraded to an error in GraalVM in JDK 26 or later.
Native Image
Improvements and New Features
- In this release, a new generation of machine learning-powered profile inference has been introduced—the Graal Neural Network (GNN) static profiler—resulting in a 7.9% peak performance improvement observed across a wide range of microservices benchmarks. To enable this optimization, pass the
-O3
option to Native Image. This feature is only available in Oracle GraalVM. Learn more in the documentation. - Introduced SkipFlow: a new experimental extension to the Native Image static analysis that tracks primitive values and evaluates branching conditions dynamically during the analysis process. SkipFlow can provide up to a 4% reduction in binary size without any additional impact on build time. The feature is available in GraalVM for JDK 24, but is not enabled by default. Enable and test it using the following options:
-H:+TrackPrimitiveValues
and-H:+UsePredicates
. This enhancement is the result of a research collaboration. Find the paper here to read more. - Added experimental support for running premain methods of Java agents at runtime. At build time, specify the premain classes using the
-H:PremainClasses
option. At runtime, provide the premain runtime options along with the main class arguments in the format-XXpremain:<class>:<options>
. (See #8988.) - Enhanced experimental Vector API support in Native Image AOT compilation, now on par with Graal JIT. To enable Vector API optimizations when building native images, use the
--add-modules jdk.incubator.vector
and-H:+VectorAPISupport
options. (See #10285.) Improvements include a greater number of optimized Vector API operations. The following operations are now efficiently compiled to SIMD code, where supported by the target hardware:- Operations on Vector API masks
- Masked Vector API loads and stores
- General Vector API rearrange operations
- Vector API loads/stores to and from memory segments
- Optimized the Foreign Function and Memory API (FFM) in Native Image by introducing specialized upcalls for direct method handles.
- Enhanced the Software Bill of Materials (SBOM) support in GraalVM Native Image to improve security and provide deeper insights into application dependencies:
- Class-level metadata inclusion: You can now include class-level metadata to the SBOM components in a native image using the
--enable-sbom=class-level,export
option. This information can be useful for advanced vulnerability scanning and better understanding of the image contents. - Dependency tree generation: The SBOM now includes a detailed dependency tree derived from the static analysis. This feature provides a hierarchical view of component dependencies within the native executable.
- Improved accuracy of the SBOM which is critical for vulnerability scanning: The GAV coordinates are now more accurate by extending parsing and handling of manifest files and integrating with the Native Image Maven plugin, reducing false-negatives. Shaded and Fat JARs are now better handled to prune redundant components and reduce false positives in vulnerability scanning.
Only available in Oracle GraalVM. Read more in the documentation.
- Class-level metadata inclusion: You can now include class-level metadata to the SBOM components in a native image using the
- Include serialization JSON reachability metadata as part of the reflection metadata by introducing the
serializable
flag for reflection entries. - Preserve the origin of a resource included in a native image. The information is included in the Build Report by default, or can be produced by passing the
-H:+GenerateEmbeddedResourcesFile
option. - Added support for
GetStringUTFLengthAsLong
in JNI. (See JDK-8328877.) - The length of the printed stack trace when using
-XX:MissingRegistrationReportingMode=Warn
can now be set with-XX:MissingRegistrationWarnContextLines=
and its default length is now 8. ActiveProcessorCount
is now required to be set during isolate or VM creation.- Optimized the
ForkJoinPool.commonPool()
builder method to consistently respect the value set byNativeImageOptions.NumberOfThreads
. - Added
DuringSetupAccess.registerObjectReachabilityHandler
to allow registering a callback that is executed when an object of a specified type is marked as reachable during heap scanning.
Platform Compatibility
-
Native Image now targets
armv8.1-a
by default on AArch64. Pass-march=compatibility
at build time for best compatibility or-march=native
for best performance if the native executable is deployed on the same machine or a machine with the same CPU features. To list all available machine types, use-march=list
. -
Added support for Java module system-based service loading. For example, defining the following in a module-info.java file:
module Foo { provides MyService with org.example.MyServiceImpl; }
Debugging and Monitoring Improvements
- Added experimental support for
jcmd
on Linux and macOS. Use the--enable-monitoring=jcmd
option to build a native image withjcmd
enabled. See the documentation for more information. - Added a possibility to debug native executables with a Python helper script, gdb-debughelpers.py, based on the GDB Python API. See the documentation to learn more.
- Updated debug info from DWARF4 to DWARF5 and now store type information in DWARF type units. Switching to DWARF5 reduces the size of debugging information by 30%.
- Added support for emitting the Windows x64 unwind information. This enables stack walking in native tooling such as debuggers and profilers.
Deprecated Functionality
- Removed the
customTargetConstructorClass
field from the serialization JSON metadata. All possible constructors are now registered by default when registering a type for serialization.RuntimeSerialization.registerWithTargetConstructorClass
is now deprecated. - Display a deprecation warning upon the first use of the legacy
graal.
prefix. This warning will be upgraded to an error in GraalVM in JDK 26 or later.
Polyglot Runtime
- Language and instrument resources are now automatically included when embedding a Graal Language in a native image. By default, a separate resources folder is no longer created next to the image. Read more in the Embedding Languages guide.
- Starting in GraalVM for JDK 24, users must configure native access privileges to the
java
executable in order to avoid warnings from being printed by the JDK. For usages of the module-path, pass the--enable-native-access=org.graalvm.truffle
option, and for class-path usages, pass the--enable-native-access=ALL-UNNAMED
option to resolve the new warning. Note that Truffle automatically forwards the native access capability to all loaded languages and tools, therefore no further configuration is required. If the native access is denied by the user with--illegal-native-access=deny
, then loading the optimizing runtime will fail and the fallback runtime will be used. More information can be found in the integrity-by-default JEP 472. Context
andEngine
is now automatically closed when no longer strongly referenced. A reachableValue
orPolyglotException
will keep the associatedContext
reachable. Additionally, theContext
remains reachable when explicitly entered or if there is an active polyglot thread within it. TheEngine
remains reachable when there is a strongly reachableLanguage
,Instrument
, orContext
instance. However, it is still recommended not to rely on garbage collection for closing. Instead, use the try-with-resources pattern for explicit context and engine management. For more information, refer to the Automatic Close on GC documentation.- Added the ability to use
Value#as(byte[].class)
to copy the contents of a guest language byte buffer(Value#hasBufferElements())
to a new byte array. The new functionality has precedence over accessing the guest object as array(Value#hasArrayElements())
if both ways are available. - Added support for creation of strings from raw byte arrays and native memory using
Value.fromByteBasedString(...)
andValue.fromNativeString(...)
.Value.StringEncoding
must be provided.
Find a complete list of updates in the changelog.
GraalJS
- Implemented several ECMAScript proposals:
- Error.isError, available in ECMAScript staging mode (
--js.ecmascript-version=staging
). - Math.sumPrecise, available in ECMAScript staging mode (
--js.ecmascript-version=staging
). - Atomics.pause, available in ECMAScript staging mode (
--js.ecmascript-version=staging
). - Promise.try, available in ECMAScript staging mode (–js.ecmascript-version=staging).
- Uint8Array to/from base64 and hex, available in ECMAScript staging mode (
--js.ecmascript-version=staging
). - RegExp.escape, available in ECMAScript staging mode (
--js.ecmascript-version=staging
). - Iterator Sequencing, available in ECMAScript staging mode (
--js.ecmascript-version=staging
). - Source Phase Imports, available behind the experimental option
--js.source-phase-imports
. - Regular Expression Pattern Modifiers, available by default.
- Error.isError, available in ECMAScript staging mode (
- Implemented the
TextDecoder
andTextEncoder
APIs of the WHATWG Encoding Standard. They are available behind the experimental option--js.text-encoding
. - Made options
js.load
,js.print
,js.graal-builtin
, andjs.locale
stable and allowed in theSandboxPolicy.UNTRUSTED
mode. - GraalJS now supports WebAssembly/ES module integration that allows
.wasm
modules to be loaded viaimport
statements. The optionjs.webassembly
is now stable.
Find a complete list of updates in the project changelog.
GraalPy
New Features
- Released the GraalPy Gradle Plugin for embedding of Python packages into Java.
- Added the experimental
python.IsolateNativeModules
option to allow loading native extensions multiple times in different contexts. See the documentation for more information. - Foreign objects are now given a Python class corresponding to their interop traits. Foreign lists now inherit from Python
list
, foreign dictionaries fromdict
, foreign strings fromstr
, foreign iterators fromiterator
, foreign exceptions fromBaseException
, foreign numbers frompolyglot.ForeignNumber
, foreign booleans frompolyglot.ForeignBoolean
, and foreign null values fromNoneType
. This means all Python methods of these types are available on the corresponding foreign objects, which behave as close as possible as if they were Python objects. When calling a method on a foreign object in Python code, Python methods are now prioritized over foreign members. Also addedpolyglot.register_interop_type
and@polyglot.interop_type
to define custom Python methods for a given foreign class ot type. See the documentation for more information.
Java Embeddings Improvements
- Introduced new types:
KeywordArguments
andPositionalArguments
in the GraalPy Embedding library (org.graalvm.python:python-embedding
), to support directly passing keyword and positional arguments from Java to Python. - Deprecated the
org.graalvm.python.embedding.util
package and added new equivalents toorg.graalvm.python.embedding
. - Maven and Gradle plugins do not embed Python home into the generated virtual filesystem. Instead, the handling of language home for any Graal Language, including GraalPy, for the GraalVM Native Image build can be controlled by new Native Image options
+H:IncludeLanguageResources
and+H:CopyLanguageResources
. By default, the whole Python home is embedded into the native executable. In the case of JVM deployment, the language home is embedded in the GraalPy artifacts at Maven Central.
Find a complete list of updates in the project changelog.
GraalWasm
- WebAssembly modules now can be loaded in JavaScript via
import
statements. GraalJS now supports WebAssembly/ES module integration. Read more here. - Implemented the Relaxed SIMD proposal. This feature can be enabled with the option
--wasm.RelaxedSIMD
. - Deprecated the
--wasm.AsyncParsingBinarySize
and--wasm.AsyncParsingStackSize
options. These options no longer have any effect and will be removed in a future release.
Find a complete list of updates in the project changelog.
Espresso
- Improvements to Espresso Continuation API: continuation suspension now clears slots based on liveness analysis. This ensures the set of captured variables is predictable and deterministic.
- Added support for automatically using generic type parameters for incoming host objects, to allow more seamless communication between host and Espresso contexts.
- Custom type converters now always take precedence over built-in converters when passing objects from the host to the embedded Espresso context.
- Espresso’s hash interop implementation now throws an unsupported operation exception when attempting to modify an unmodifiable guest map.
Polyglot.cast()
now applies custom type converters and interface type mappings, same asPolyglot.castWithGenerics()
.- The
<ProcessReferences>
builtin no longer hangs when multi-threading is disabled.
Find a complete list of updates in the project changelog.
TruffleRuby
- Updated to Ruby 3.3.5.
Polyglot::ForeignException
now inherits fromStandardError
instead ofException
.- Added support for OpenSSL versions 1.1 through 3.4, with preference given to OpenSSL 3.0.x, followed by 3.x, and 1.1 (End of Life). Resolved a compilation issue with OpenSSL 3.4.
- Improved the speedup of some C extensions like
sqlite3
,trilogy
, andjson
by 2 to 3 times by using the Panama NFI backend for faster upcalls in the JVM mode. - Optimized encoding negotiation for ASCII-compatible encodings.
Find a complete list of updates and bug fixes in the TruffleRuby changelog.
Truffle Language Implementation Framework
- Added the experimental Bytecode DSL, a new framework for implementing bytecode interpreters. The Bytecode DSL automatically generates a complete bytecode interpreter from a set of user-specified operations. The generated interpreter defines all the necessary components of a bytecode interpreter, including an instruction set, a bytecode generator, and an optimizing interpreter. Bytecode DSL interpreters are designed to improve footprint and interpreter speed over AST interpreters without compromising peak performance. Bytecode DSL interpreters support a variety of features, including tiered interpretation, bytecode quickening, and boxing elimination, continuations, and serialization. They also integrate with existing Truffle tooling for instrumentation and debugging. See the Introduction to Bytecode DSL to get started, or check the user guide for more information. The Bytecode DSL is experimental in this release.
- Java Native access for JEP 472: Prepare to Restrict the Use of JNI is now automatically provided for all languages and tools by Truffle.
- Added the
TruffleLanguage.Env.getHostLanguage()
method returning the host language info. This allows languages to lookup the top scope of the host language usingEnv.getScopeInternal(LanguageInfo)
. - Added the
@Bind.DefaultExpression
annotation. Default expressions allow you to omit an explicit expression when declaring a@Bind
parameter (the default expression for the parameter’s type is used). - Added
RootNode.findInstrumentableCallNode(...)
that allows resolving the instrumentation location given a call node, frame, and bytecode index. This allows to store instrumentable nodes in a side data structure for bytecode interpreters. Also theTruffleStackTraceElement.getInstrumentableLocation()
andFrameInstance.getInstrumentableCallNode()
methods were added to access the resolved locations. Tools using the Truffle instrumentation framework are encouraged to use these APIs instead for the purpose of accessing node locations.
Find a complete list of updates in the Truffle changelog.