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

OwnerJohn Rose
TypeFeature
ScopeJDK
StatusCandidate
Componenthotspot / runtime
Discussionleyden dash dev at openjdk dot org
EffortM
DurationS
Relates toJEP 483: Ahead-of-Time Class Loading & Linking
Reviewed byAlex Buckley, Vladimir Kozlov
Created2025/02/13 18:07
Updated2025/04/30 14:29
Issue8350022

Summary

Make it easier to create ahead-of-time caches, which accelerate the startup of Java applications, by simplifying the commands required for common use cases.

Goals

Non-Goals

Motivation

Ahead-of-time caches, introduced by JEP 483, accelerate the startup of Java applications. Their benefits are expected to grow as Project Leyden brings new AOT-related optimizations to the HotSpot JVM.

With JDK 24, you create an AOT cache in two steps, invoking the java launcher in two distinct AOT modes. The first invocation specifies record mode, directing the JVM to observe the dynamics of a training run of your application and record them into an AOT configuration. The second invocation specifies create mode, directing the JVM to create an AOT cache based on the configuration recorded during the training run.

Here is an example of this two-step workflow, taken from JEP 483:

$ java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf \
       -cp app.jar com.example.App ...

$ java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf \
       -XX:AOTCache=app.aot

Subsequently, you run your application specifying just the AOT cache:

$ java -XX:AOTCache=app.aot -cp app.jar com.example.App ...

This production run of the application starts more quickly because the application's classes do not need to be discovered, loaded, and linked. They are available instantly from the cache.

It is inconvenient to have to run java twice in order to create an AOT cache. It is also inconvenient to have the AOT configuration file left over — it is just a temporary file, not required for production runs, and can be deleted.

It would be far more convenient if, at least in common use cases, only one step were needed to perform a training run and create an AOT cache. This would be efficient for users and also convenient for applications such as JRuby that coordinate their own training against custom workloads. The ability to specify AOT modes and AOT configurations explicitly can remain for uncommon use cases.

Description

We extend the java launcher with a new command-line option, AOTCacheOutput, that specifies an AOT cache output file. When used alone, with no other AOT options, this option causes the launcher to, in effect, split its invocation into two sub-invocations: The first does a training run (AOTMode=record) and then the second creates the AOT cache (AOTMode=create).

For example, the two-step workflow shown earlier can be replaced by the single step:

$ java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App ...

As a convenience, when operating in this way the JVM creates a temporary file for the AOT configuration and deletes the file when finished.

A production run that uses the AOT cache is started the same way as before:

$ java -XX:AOTCache=app.aot -cp app.jar com.example.App ...

A new environment variable, JAVA_AOT_OPTIONS, can be used to pass command-line options that apply specifically to cache creation (AOTMode=create), without affecting the training run (AOTMode=record). The syntax is the same as for the existing JAVA_TOOL_OPTIONS environment variable. This enables the one-step workflow to apply even in use cases where it might seem that two steps are necessary due to differences in the command-line options.

The full specification of these options is available here.

Manually orchestrating training and cache creation

There are still use cases where it may be preferable to use two steps to create an AOT cache, specifying the AOT mode explicitly each time.

For example, if you intend to deploy an application to small instances in a cloud then you could do the training run on a small instance but create the AOT cache on a large instance. That way the training run reflects the deployment environment, but the creation of the AOT cache can leverage the additional CPU cores and memory of the large instance.

Such a division of labor may become more important as Leyden AOT optimizations become more complex. For example, some future AOT optimization might require minutes of time to create a cache on a small instance, but just seconds on a large instance.

Alternatives