|
| 1 | +[[class-data-sharing]] |
| 2 | += Class Data Sharing |
| 3 | + |
| 4 | +Class Data Sharing (CDS) is a https://docs.oracle.com/en/java/javase/17/vm/class-data-sharing.html[JVM feature] |
| 5 | +that can help reduce the startup time and memory footprints of Java applications. |
| 6 | + |
| 7 | +To use this feature, a CDS archive should be created for the particular classpath of the |
| 8 | +application. The Spring Framework provides a hook-point to ease the creation of the |
| 9 | +archive. Once the archive is available, users should opt in to use it via a JVM flag. |
| 10 | + |
| 11 | +== Creating the CDS Archive |
| 12 | + |
| 13 | +A CDS archive for an application can be created when the application exits. The Spring |
| 14 | +Framework provides a mode of operation where the process can exit automatically once the |
| 15 | +`ApplicationContext` has refreshed. In this mode, all non-lazy initialized singletons are |
| 16 | +instantiated, `InitializingBean#afterPropertiesSet` callbacks have been invoked, but the |
| 17 | +lifecycle has not started and `ContextRefreshedEvent` has not been published. |
| 18 | + |
| 19 | +To create the archive, two additional JVM flags must be specified: |
| 20 | + |
| 21 | +* `-XX:ArchiveClassesAtExit=app-cds.jsa`: creates the CDS archive on exit |
| 22 | +* `-Dspring.context.exit=onRefresh`: starts and then immediately exit your Spring |
| 23 | + application as described above. |
| 24 | + |
| 25 | +To create a CDS archive, your JDK must have a base image. If you add the flags above to |
| 26 | +your startup script, you may get a warning that looks like this: |
| 27 | + |
| 28 | +[source,shell,indent=0,subs="verbatim"] |
| 29 | +---- |
| 30 | + -XX:ArchiveClassesAtExit is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info. |
| 31 | +---- |
| 32 | + |
| 33 | +The base CDS archive can be created by issuing the following command: |
| 34 | + |
| 35 | +[source,shell,indent=0,subs="verbatim"] |
| 36 | +---- |
| 37 | + $ java -Xshare:dump |
| 38 | +---- |
| 39 | + |
| 40 | +== Using the Archive |
| 41 | + |
| 42 | +Once the archive is available, add `-XX:SharedArchiveFile=app-cds.jsa` to your startup |
| 43 | +script to use it, assuming a `app-cds.jsa` file in the working directory. |
| 44 | + |
| 45 | +To figure out how effective the cache is, you can enable class loading logs by adding |
| 46 | +an extra attribute: `-Xlog:class+load:file=cds.log`. This creates a `cds.log` with every |
| 47 | +attempt to load a class and its source. Classes that are loaded from the cache should have |
| 48 | +a "shared objects file" source, as shown in the following example: |
| 49 | + |
| 50 | +[source,shell,indent=0,subs="verbatim"] |
| 51 | +---- |
| 52 | + [0.064s][info][class,load] org.springframework.core.env.EnvironmentCapable source: shared objects file (top) |
| 53 | + [0.064s][info][class,load] org.springframework.beans.factory.BeanFactory source: shared objects file (top) |
| 54 | + [0.064s][info][class,load] org.springframework.beans.factory.ListableBeanFactory source: shared objects file (top) |
| 55 | + [0.064s][info][class,load] org.springframework.beans.factory.HierarchicalBeanFactory source: shared objects file (top) |
| 56 | + [0.065s][info][class,load] org.springframework.context.MessageSource source: shared objects file (top) |
| 57 | +---- |
| 58 | + |
| 59 | +TIP: If you have a large number of classes that are not loaded from the cache, make sure that |
| 60 | +the JDK and classpath used by the commands that create the archive and start the application |
| 61 | +are identical. |
0 commit comments