This feature has existed in Java since Java 5. It was extended in Java 9 as a commercial feature by allowing not only bootstrap classes but also application classes to be placed in the archive shared by JVMs. In Java 10, this feature became part of the open JDK. It decreases startup time and, when several JVMs are running on the same machine with the same application being deployed, reduces memory consumption.
Using application class-data sharing
Getting ready
The advantages of loading classes from the shared archive became possible for two reasons:
- The classes stored in the archive are preprocessed, which means that the JVM memory mapping is stored in the archive too. It reduces the overhead of class-loading when a JVM instance starts.
- The memory region can even be shared between the JVM instances running on the same computer, which reduces overall memory consumption by eliminating the need to replicate the same information in each instance.
The new JVM functionality allows us to create a list of classes to be shared, then use this list to create a shared archive, and use the shared archive to fast-load archived classes into memory.
How to do it...
- By default, JVM can create an archive using the list of classes that comes with JDK. For example, run the following command:
java -Xshare:dump
It will create the shared archive as a classes.jsa file. On a Linux system, this file is placed in the following folder:
/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home/lib/server
C:\Program Files\Java\jdk-11\bin\server
If this folder is accessible by the system admin only, run the command as an admin.
Please notice that not all classes can be shared. For example, the .class files located in the directory on the classpath and classes loaded by custom class loaders cannot be added to the shared archive.
- To tell the JVM to use the default shared archive, use the following command:
java -Xshare:on -jar app.jar
The preceding command maps the content of the archive at a fixed address. This memory-mapping operation may occasionally fail when the required address space is not available. If that happens when the -Xshare:on option is used, the JVM exits with an error. Alternatively, the -Xshare:auto option can be used, which just disables the feature and loads the classes from the classpath if the shared archive cannot be used for whatever reason.
- The simplest way to create a list of loaded application classes is by using the following command:
java -XX:+UseAppCDS -XX:DumpLoadedClassList=classes.txt -jar app.jar
The preceding command records all the loaded classes in the classes.txt file. If you would like to make your application load faster, stop the JVM just after the application has been started. If you need it to load certain classes faster but these classes are not loaded at the application startup automatically, make sure that the use cases that require these classes are executed.
- Alternatively, you can manually edit the classes.txt file and add/remove any classes you need to put in the shared archive. Create this file once automatically and see the format. It is a simple text file that lists one class in each line.
- Once the list is created, use the following command to generate the shared archive:
java -XX:+UseAppCDS -Xshare:dump -XX:SharedClassListFile=classes.txt -XX:SharedArchiveFile=app-shared.jsa --class-path app.jar
Notice that the shared archive file has a name other than classes.jsa, so the default shared archive is not overwritten.
- Use the created archive by executing the following command:
java -XX:+UseAppCDS -Xshare:on -XX:SharedArchiveFile=app-shared.jsa -jar app.jar
Again, you can use the -Xshare:auto option to avoid an unexpected exit of the JVM.
The effect of the shared archive usage depends on the number of classes in it and other particulars of the application. So, we recommend you experiment and test various configurations before committing to a certain list of classes in production.