JDK-8185996 : JEP 310: Application Class-Data Sharing
  • Type: JEP
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P2
  • Status: Closed
  • Resolution: Delivered
  • Fix Versions: 10
  • Submitted: 2017-08-08
  • Updated: 2023-08-24
  • Resolved: 2018-03-08
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8188791 :  
JDK-8188792 :  
Description
Summary
-------

To improve startup and footprint, extend the existing Class-Data Sharing
("CDS") feature to allow application classes to be placed in the shared
archive.

Goals
-----

  - Reduce footprint by sharing common class metadata across different
    Java processes.

  - Improve startup time.

  - Extend CDS to allow archived classes from the JDK's run-time image
    file (`$JAVA_HOME/lib/modules`) and the application class path to be
    loaded into the built-in platform and system class loaders.

  - Extend CDS to allow archived classes to be loaded into custom class
    loaders.

Non-Goals
---------

  - The shared-class archive storage format used in this implementation
    will not be standardized.

  - In this release, CDS cannot archive classes from user-defined modules
    (such as those specified in `--module-path`). We plan to add that
    support in a future release.

Success Metrics
---------------

This project will be considered successful if we can achieve (1)
significant space saving in the memory used by Java class metadata across
multiple JVM processes, and (2) significant startup time improvements.

For illustrative purposes:

  - We can save about 340MB of RAM for a Java EE app server that includes
    6 JVM processes consuming a total of 13GB of RAM (~2GB of that is for
    class meta data).

  - We can improve the startup time of the JEdit benchmark by 20-30%.

  - We can reduce the RAM usage of the embedded Felix benchmark by 18%
    across 4 JVM processes.

These numbers reflect specific benchmarks and may not be generally
applicable.  The benefit of this work depends on the number of classes
loaded by the supported class loaders as well as the heap usage of the
application as a whole.

Description
-----------

Class-Data Sharing, introduced in JDK 5, allows a set of classes to be
pre-processed into a shared archive file that can then be memory-mapped
at runtime to reduce startup time. It can also reduce dynamic memory footprint
when multiple JVMs share the same archive file.

Currently CDS only allows the bootstrap class loader to load archived
classes.  Application CDS ("AppCDS") extends CDS to allow the built-in
system class loader (a.k.a., the "app class loader"), the built-in platform
class loader, and custom class loaders to load archived classes.

Analysis of the memory usage of large-scale enterprise applications shows
that such applications often load tens of thousands of classes into the
application class loader. Applying AppCDS to these applications will
result in memory savings of tens to hundreds of megabytes per JVM
process.

Analysis of serverless cloud services shows that many of them load several
thousand application classes at start-up. AppCDS can allow these services to
start up quickly and improve the overall system response time.

### Enabling AppCDS

By default, Class-Data Sharing is enabled only for the JVM's bootstrap
class loader. Specify the `-XX:+UseAppCDS` command-line option to
enable class data sharing for the system class loader (a.k.a. "app
class loader"), the platform class loader, and other user-defined class
loaders.

### Determining the classes to archive

An application may be packaged with a large number of classes but use
only a fraction of them during normal operation. By archiving only the
classes that are used, we can reduce the file storage size and runtime
memory usage. To do this, first run the application normally with
`-Xshare:off`, and use the `-XX:DumpLoadedClassList` command-line option
to record all the classes that are loaded.

Note that `-XX:DumpLoadedClassList` by default includes only the
classes loaded by the bootstrap class loader. You should specify the
`-XX:+UseAppCDS` option so that classes loaded by the system class loader
and platform class loader are also included.  For example:

```
java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld
```

### Creating the AppCDS archive

To create the AppCDS archive, specify the `-Xshare:dump
-XX:+UseAppCDS` command-line options, pass the list of classes with
the `-XX:SharedClassListFile` option, and set the classpath to be the
same as used by your application. You should also use the
`-XX:SharedArchiveFile` option to specify the name of the archive file
to store the classes. Note that if `-XX:SharedArchiveFile` is not
specified then the archived classes will be stored into the JDK's
installation directory, which is typically not what you want to do.
For example:

```
$ java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst \
    -XX:SharedArchiveFile=hello.jsa -cp hello.jar
```

### Using the AppCDS archive

Once the AppCDS archive is created, you can use it when starting the
application.  Do this by specifying the `-Xshare:on -XX:+UseAppCDS`
command-line options, with the `-XX:SharedArchiveFile` option to indicate
the name of the archive file. For example:

```
$ java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa \
    -cp hello.jar HelloWorld
```
### Classpath mismatch

The classpath used with `-Xshare:dump` must be the same as, or be a
prefix of, the classpath used with `-Xshare:on`. Otherwise, the JVM
will print an error message about the mismatched classpath and refuse
to start. To analyze the mismatch, you can add `-Xlog:class+path=info`
to the application's command-line, and the JVM will print out detailed
diagnostic information about what classpath is expected, and what
classpath is actually used.

### Using `-Xshare:auto`

AppCDS works by memory-mapping the contents of the archive at a fixed
address. On some operating systems, especially when address
space layout randomization (ASLR) is enabled, the memory-mapping
operation may occassionally fail when the required address space is
not available. If the `-Xshare:on` option is specified, the JVM will
treat this as an error condition and fail to start. To make your
application more resilient in such situations, we recommend that the
`-Xshare:auto` option to be used instead. This way, when the JVM fails
to memory-map the archive, it will disable AppCDS and continue to run
the application normally.

Please note that `-Xshare:auto` will also disable AppCDS if there's a
classpath mismatch. Therefore, we recommend that you first test with
`-Xshare:on` to ensure there's no classpath mismatch, and then use
`-Xshare:auto` in the production environment.

### Listing the Classes Loaded from the AppCDS Archive

To find out what classes have been loaded from the AppCDS archive, you
can use the `-Xlog:class+load=info` command-line option, which prints
out the name of each loaded class, as well as from where the class is
loaded. Classes loaded from the CDS archive will be printed as
`source: shared objects file`.  For example:

```
$ java -Xshare:on   -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa \
    -cp hello.jar -Xlog:class+load=info HelloWorld | grep HelloWorld
[0.272s][info][class,load] HelloWorld source: shared objects file
```
### Implementation

 - *Platform and system class loaders:* The HotSpot VM recognizes
   class-loading requests from the built-in platform and system class
   loaders.  When these loaders request a class that exists in the CDS
   archive then the VM skips the usual class-file parsing and
   verification steps and loads the archived copied of the class.

 - *Custom class loaders:* When a custom class loader invokes
   `ClassLoader::defineClass`, the VM attempts to match the contents of
   the class file with an archived class by comparing fingerprints of the
   class-file data.  If a match is found, the VM skips the class-file
   parsing and verification steps and directly loads the archived copy of
   the class.

Alternatives
------------

We considered using a shared-memory region to share classes that are
dynamically loaded by multiple live JVM processes, but we found the
sharing potential to be lower and the implementation to be more
difficult.

We have, instead, chosen to make the application class-data sharing more
static:

  - An extra 'dump' step is required.

  - When the application's JAR files are updated, the dump step needs to
    be repeated.

This is built on top of the existing CDS infrastructure, so the
implementation is simpler and we can achieve a higher ratio of sharing
with our target use cases.

Testing
-------

Extensive testing is needed to ensure compatibility and confirm
performance benefits.

Testing should be performed on all supported platforms.  On some
platforms (especially Windows/x86) tests may fail if the JVM is unable to
map the archive due to Address Space Layout Randomization (ASLR).


Risks and Assumptions
---------------------

AppCDS was previously implemented in the Oracle JDK for JDK 8 and JDK 9.
This JEP moves the source code to the open repository in order to make
the feature generally available.  Because AppCDS has been extensively
tested in JDK 8 and JDK 9, the risk to compatibility and stability is
low.

Comments
https://github.com/openjdk/jdk/commit/61e736cbae980433d5b4e547a7d2f159063bced0
03-10-2022

Requesting TOIs - Format, duration, and content to be determined at a later date.
20-12-2017

There are only a few flags related to AppCDS. I've added a description of them and a simple example.
02-11-2017

Linking to old Oracle JDK documentation that instructs the user to use the -XX:+UnlockCommercialFeatures option is better than nothing but still confusing. Please write up some basic text for inclusion in the Description section of this JEP. All I'm asking for are descriptions of what the relevant -XX flags mean and an example of how to use them. Have a look at JEP 261 (http://openjdk.java.net/jeps/261), for the module system, for one way to do this (though that's obviously a more complex JEP). In any case, please follow the JEP template (http://openjdk.java.net/jeps/2). There is no "Notes" section.
01-11-2017

When AppCDS was implemented as a closed feature in JDK 8 and 9, the documentation was already publicly available. Should I simply include this link in the JEP itself? https://docs.oracle.com/javase/9/tools/java.htm#JSWOR-GUID-31503FCE-93D0-4175-9B4F-F6A738B2F4C4 User modules are not support (although we are planning to add the support in future releases). I will add a note to the "non goals".
27-10-2017

Suggestion: A JEP should contain enough information to enable a skilled developer to experiment with the feature that it defines. In this case, if I've never used the closed version of this technology then how do I know what to put into the shared class list file, how do I know when to use the -Xshare:dump option, and why would I want to put the archive file somewhere else? What you have here now is more of a design document, which is fine and useful, but please add a bit more text to show a typical use case and cover other aspects of its use in practice. Question: It's not clear whether this mechanism supports code in modules on the module path. You mention modules in the goals, but only those in the run-time image, and you only discuss the class path as a source of user classes in the description. Are user modules supported by this mechanism?
26-10-2017

Good. Thanks!
09-09-2017

[~kvn] IgnoreUnverifiableClassesDuringDump will become true by default -- see JDK-8187347
08-09-2017

Looks good. Yay! Suggest removing the Notes section and referencing the closed JEPS into the Risks and Assumptions section where you reference them. Also please add JEP C49 to the issue links. Our open customers can't read them, so useful as references, but not the way to start, and not the JEP format.
31-08-2017

1. Whould be nice to add an example. 2. Also document IgnoreUnverifiableClassesDuringDump diagnostic flag without which I was not able to generate CDS archive in several cases. May be it should be default behavior - skip unverifiable classes and generate CDS archive. And have opposite flag which enforce verification passing.
30-08-2017