Welcome, GraalVM for JDK 23!

Alina Yurenko
graalvm
Published in
9 min readSep 17, 2024

Today we are releasing GraalVM for JDK 23!

As always, we release GraalVM on the same day that Oracle JDK and OpenJDK are released, so you can immediately use the latest features with one download!

You can already download GraalVM and check the release notes for more details. Keep reading this blog post to see what’s new in this release.

You can also check out our release stream:

GraalVM for JDK 23

You can use GraalVM as your JDK 23 distribution with access to the latest features and the highly optimizing Graal JIT.

In this release, we implemented several new JEPs, such as 455: Primitive Types in Patterns, instanceof, and switch (Preview), 473: Stream Gatherers (Second Preview), 480: Structured Concurrency (Third Preview), 481: Scoped Values (Third Preview), and others — you can learn more in the release notes.

You can enable preview features by passing --enable-preview.

Native Image

Now, let’s talk about the Native Image updates!

Faster applications, less memory 🚀🌿

With every release we are tracking multiple performance metrics, to make sure that with Native Image you get the best possible peak performance in addition to fast startup and low memory usage.

Performance of Spring Petclinic with Oracle GraalVM Native Image and GraalVM CE JIT. The benchmarking experiment ran the latest Spring Petclinic on Ampere A1 servers, restricting the workload to 16 CPUs and setting a maximum heap size of 512MB.

There has never been a better time to try out Native Image!

New Compacting Garbage Collector

In this release, we added a mark & compact GC for the old generation of the Serial GC (available in both Oracle GraalVM and GraalVM Community). The primary intention is to reduce the max memory usage compared to the copying GC, which can use 2x the current heap size when all objects survive. We recommend checking out this GC if you want to use small heap sizes, or are deploying to memory-constrained environments and optimize for smaller containers.

Memory usage reduction with the new Compacting Garbage Collector

As shown above on the example of the Scrabble benchmark, in this case the Compacting Garbage Collector can lead to around 20% lower memory usage. While memory usage might go down, there is also no performance penalty — peak throughput of the application stays the same 🚀

Smaller executables

We have added a new optimization level in Native Image, -Os. We used to get requests from users who want to have smaller executables, and while it was possible before as well with other tools, it’s certainly much easier now with -Os. This option will configure the build to optimize for the smallest code size, and therefore the smallest executable size. Under the hood it enables all -O2 optimizations except those that can increase the image size.

Here’s an example of a basic Spring Boot web application, built with GraalVM for JDK 23. With the optimized for size mode, the native application is 35% smaller!

New optimization mode in Native Image: optimize for size

Beware though that this mode is great for image size, but it might not be the best for peak throughput — benchmark and choose the optimization level based on your goals.

New SBOM Integration 🛡️

Native Image can generate native executables with an embedded software bill of materials (SBOM), that you can use for supply chain security analysis. Previously the SBOM file was always embedded in the native image. Now we also added a feature to include SBOM as a Java resource on the classpath at META-INF/native-image/sbom.json. To do this, pass the --enable-sbom=classpath to the build.

What’s great about having the SBOM on classpath is that you can then explore it with standard tools, such as Spring Actuator. Built-in support is underway, but you can already give it a try in a few simple steps:

  1. Generate your Spring project and include Native Image support, Spring Web, and Spring Actuator, or clone our example.
  2. in native-maven-plugin, add configuration to put SBOM on the classpath via --enable-sbom=classpath.
  3. Build:
mvn -Pnative native:compile

4. Run:

./target/demo

5. Curl the Actuator endpoint to retrieve the SBOM:

curl http://localhost:8080/actuator/sbom/native-image

All done!🎉 You can now explore your project’s dependencies and their metadata. You can also use the SBOM to identify known CVEs in your application by running it through a vulnerability scanner of your choice.

Better Build Reports

We’ve made several updates to Build Reports. Starting with GraalVM for JDK 23, to produce build reports, use the build option --emit build-report (or emit=build-report). This will emit an HTML report, where you can find code breakdown that shows how different packages relate to each other in terms of bytecode size and method count. Note that those are only the methods found reachable by the static analysis.

Method-based code area breakdown

We also added a new Resources view. You can use this view to explore the Java resources included in the native image, their origin, and how their size contributes to the overall file size. This is useful, for example, to detect resources that are accidentally included or missing due to incorrect reachability metadata. Accidentally included resources can bloat your images and unintentionally leak information. Missing resources, for example locales missing for certain languages, can cause problems at runtime. The tab also shows you whether a resource is a file or directory, and whether it originates from the class and module path or got injected programmatically — for example by a framework.

Resource in Build Reports

Extend your Java applications with Python and Wasm libraries 📚

GraalVM always offered smooth, fast, and easy interoperability between multiple languages. Now extending your Java application with cool data science libraries from Python, or low-level packages from Wasm, got even easier. GraalPy and GraalWasm are now considered stable and suitable for production workloads. For GraalPy, our priority is on pure Python code and Jython use cases. And languages are now just normal Maven dependencies — see how you can get started for your project, or try out our demo. See also the Graal languages blog post for more details.

Foreign Function & Memory API in Native Image 🤖

In this release, we improved the Foreign Function & Memory API (JEP 454) implementation by adding experimental support for upcalls from foreign functions (part of “Project Panama”). This is done in addition to foreign functions downcalls and foreign memory functionality, that were available in Native Image before.

Currently, foreign calls are supported on the x64 architecture. To give it a try, build your image with -H:+ForeignAPISupport.

Native Image Developer Experience Improvements

As always, with every release we improve and polish the developer experience. Some of the updates in this release include:

  • We enabled the registration of Proxy classes into the reflection configuration by adding proxy-type entries. The configuration file proxy-config.json is now deprecated, but will still be honored. The new format to specify proxy classes is the following:
{
"type": { "proxy": [
"InterfaceName1",
"InterfaceName2",
...
]},
... (member registrations)
}
  • We added support for glob patterns to specify file path to a resource in addition to Java regular expressions. The Tracing Agent also adopted this new format. The entries can now look like this:
{
"resources": [
{
"glob": "assets/**"
},
{
"module": "myJavaModule",
"glob": "images/**/*.png"
}
]
}
  • We introduced a new --static-nolibc API option to build mostly static native executables. It replaces the experimental -H:±StaticExecutableWithDynamicLibC option.
  • Keep in mind that the old class initialization strategy, which was deprecated in GraalVM for JDK 22, is now removed.

You can find more details in the release notes.

Native Memory Tracking

The Native Memory Tracking is a JVM feature that tracks internal memory usage of HotSpot. As a first step to supporting NMT, PR #7883 added support for tracking mallocs/calloc/realloc in Linux (contribution by Red Hat). Virtual memory tracking support and support for NMT JFR events will be added in subsequent PRs.

Native Build Tools and GraalVM Reachability Repository 🛠️

GraalVM Reachability Metadata Repository enables sharing and reusing metadata of libraries in the Java ecosystem, in particular for Native Image builds. The latest release, 0.3.8, includes configuration for Flyway 10.10, itext, Hibernate Reactive, Hibernate Core 6.5.0, and several other updates. If you are using Native Build Tools, or one of the frameworks that leverage them under the hood, access to the Reachability metadata is enabled by default.

We’ve also made several changes and improvements in the recent Native Build Tools release — make sure you upgrade to 0.10.3, if you haven’t already.

Native Image Layers 📦

One of the big projects we are working on right now is Native Image Layers. With Layers you’ll be able to create native images that depend on one or more base images. This way every time you recompile your application, you only need to recompile your user code, taking compilation times down to seconds. We’ve laid the groundwork for Layers, defined the API, and are actively working on the project. Stay tuned for more updates!

Native Kafka Broker

Apache Kafka 3.8.0 introduced support for GraalVM Native Image based Brokers!🔥 As they explain in the improvement proposal, they explored Native Image as a way to improve developer experience by enabling launching brokers with sub-second startup time and minimal memory footprint by leveraging a GraalVM based native Kafka binary. Here are some measurements and observations from the team:

Native Kafka broker vs running on the JVM (Openjdk 17.0.8, Oracle GraalVM Native Image 17.0.8+9.1)
  • The startup time of the GraalVM broker is ~1/9th of the startup time of the JVM broker 🚀
  • No CPU spike is observed for GraalVM broker but JVM broker had sudden spikes both when the broker started and also when the load testing started.
  • Considerable difference in memory usage is observed as well. For JVM broker the max memory usage went up to ~1GB as compared to the ~500MB in case of GraalVM broker with G1GC and ~250MB in case of GraalVM broker with serial GC.

We are very excited about this change and the opportunities that it offers for the Kafka community, in particular for unit testing and local development!

New Community Mascot

We have a new community mascot!

GraalVM Community Mascot

Think of them as a friend of the Java Duke — you can use them in your blog posts, conference talks, demos, and anywhere you talk about GraalVM! Better yet, as you can see it’s quite versatile, and can be modified even further — we would love to see your creative options! You can grab the sources from our website.

You might have noticed that our mascot is missing a name. While we have multiple ideas (and some strong opinions), we would love to hear from you, our community — what should be the mascot’s name?🤔 Help us choose in the comments or on social media!

Community and Ecosystem

Our main repository, https://github.com/oracle/graal, reached 20K stars on GitHub!⭐️ Thank you for your contributions, feedback, and support!

Here are also more news and updates from our community

  • GraalVM Community Summit will happen for the fourth time this year! We are very excited to meet again our partners in the ecosystem and work together on the project roadmap.
  • The“State of Spring” survey results are out, and there are some interesting results. 11% of Spring Boot users already run GraalVM natively compiled applications in production, 26% of users are currently evaluating, and 31% are planning to develop native applications with GraalVM!
  • Learn how Dynatrace enables comprehensive observability, including end-to-end distributed tracing, for Native Image applications: https://www.youtube.com/watch?v=YOddFfi5Qeg.
  • There has been a very nice guide about Server-Side Rendering with Spring Boot, React, and GraalVM by Ahmad Osman.
  • Vaadin works like a charm with Native Image to help you easily bootstrap and build full-stack Java applications — see how.
  • Did you know that Maven’smvnd client is a native executable built using GraalVM?
  • See how you can work with Thymeleaf Layouts and GraalVM using Fragment Expressions in this blog post by Siva Prasad Reddy K.

Conclusion

We’d like to take this opportunity to thank our amazing contributors and community for all the feedback, suggestions, and contributions that went into this release.

If you have feedback for this release or suggestions for features that you would like to see in future releases, please share them with us on Slack, GitHub, or Twitter.

Now go ahead and try the new GraalVM! 🚀

— the GraalVM team

--

--

Alina Yurenko
graalvm

I love all things tech & community. Developer Advocate for @graalvm, blog posts about programming, open source, and devrel.