Contents

What's New in Project Leyden - JEP 514 and JEP 515 Explained

What's New in Project Leyden - JEP 514 and JEP 515 Explained webp image

Project Leyden is an ongoing initiative aimed at reducing the startup and warmup time of the Java Virtual Machine. The first completed JEP, identified as JEP 483, was introduced in JDK 24. The upcoming release of JDK 25 will include two additional JEPs:

In this blog post, I would like to describe both of these enhancements.

JEP 514 - Ahead-of-Time Command-Line Ergonomics

At the beginning, a few words of explanation for those who have already read my previous blog post: How to Improve JVM-Based Application Startup Time. I wrote there that to use Project Leyden, all you need to do is just include this single option in your application run command:

-XX:CacheDataStore=myapp.aot

However, this was true only for the early access build of JDK 24 (build 24-leydenpremain+2-8). Starting with the official release of JDK 24, this has changed.

In JDK 24, there is no such flag as CacheDataStore. Instead, we have a few others:

  • AOTCache
  • AOTClassLinking
  • AOTConfiguration
  • AOTMode

Usage of Project Leyden was split into three parts:

  1. Training run of application was necessary to record the AOT configuration:
java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -jar my-app.jar
  1. Then, the created configuration was used for cache creation with such command:
java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -jar my-app.jar
  1. Finally, we can benefit from the created cache in all subsequent runs:
java -XX:AOTCache=app.aot -jar my-app.jar

JEP 514 has simplified the process. Instead of executing three separate commands, we now only need to run two. The first command handles both recording the AOT configuration and creating the cache. The second command remains unchanged and is used to run the application.

It is possible, since a new command-line option appeared in JDK 25: AOTCacheOutput. When used alone, it effectively splits a single Java launcher invocation into two sub-invocations. The command is structured as follows:

java -XX:AOTCacheOutput=app.aot -jar my-app.jar

There are two separate commands processed under the hood. The first command uses AOTMode=record, which creates the AOT configuration. The second command uses AOTMode=create, which utilizes the configuration generated by the first command to create an AOT cache in a file specified by the AOTCacheOutput option. This process is detailed in the issue related to this JEP:

"It is much easier to explain one command splitting into two sub-commands running under two pre-existing modes, than to explain the interactions of a new combined mode with all other VM features. That is why we choose not to invent a new mode such as record+create."

One of the benefits of this approach is that the AOT configuration file is created automatically and deleted after the cache is generated. In the previous approach, this process had to be done manually. In that case, the name of the AOT configuration file is created by adding the ‘.config’ suffix to the file name specified by the AOTCacheOutput option. For example, if the original file is named app.aot the configuration file will be named app.aot.config.

If someone wants to override this default naming convention, it is also possible. Users can specify the AOTConfiguration option, just as before. In this case, the name provided within the option will be used, and the file will not be deleted automatically.

Another interesting feature is the introduction of a new environment variable, JDK_AOT_VM_OPTIONS. Its syntax is the same as that of the existing JAVA_TOOL_OPTIONS. We can utilize it to override VM options passed to the cache creation sub-invocation. Thus, JAVA_TOOL_OPTIONS will be propagated to both sub-invocations (record and create), while JDK_AOT_VM_OPTIONS will only be used for the create sub-invocation.

In summary, the described JEP simplifies how we can use Project Leyden, but the previous approach can still be utilized if needed.

JEP 515 Ahead-of-Time Method Profiling

As I mentioned earlier, the primary goal of Project Leyden is to enhance the startup and warmup time of applications. This JEP specifically addresses warmup time.

The JVM can identify code that is executed most frequently or consumes the most CPU time, and optimizes this code by compiling it into native code. This process is known as profiling. In simple terms, a profile is a collection of useful information associated with a method, such as the number of times it has been executed.

When an application is run in the usual manner (without an AOT cache), these profiles are gathered at the start of the application's execution. The concept behind this JEP is that we can collect profiles during a training run and later reuse them for subsequent runs. This means that in later executions, there is no need to collect profiles after startup, allowing code compilation to begin immediately.

It's important to note that the quality of the training run significantly affects the improvement in warmup time for the application. The better the training run, the greater the performance enhancement achieved during subsequent runs.

The Ahead-of-Time Method Profiling JEP does not introduce new workflows but utilizes existing ones. It also does not require any changes to the codebase. Essentially, it shifts some work from production runs to training runs.

Conclusion

It is good to see that work on Project Leyden keeps ongoing. With these two JEP’s which will be introduced within JDK 25, we will get improvements regarding its usability and warmup time. What is very important is that Project Leyden integrates seamlessly with existing code bases.

I look forward to seeing the next features.

Read also: Java: Three Decades, Three Lessons

Reviewed by Szymon Winiarz

Blog Comments powered by Disqus.