Volker Simonis, SAP / volker.simonis@gmail.com
$ java -Xshare:dump
Allocated shared space: 3221225472 bytes at 0x0000000800000000
Loading classes to share ... // from JAVA_HOME/lib/classlist
Rewriting and linking classes ... // Verification, ...
Number of classes 1240
Removing unshareable information ... done.
Relocating embedded pointers ...
Dumping symbol table ...
Dumping String objects to closed archive heap region ...
Removing java_mirror ... done. // java.lang.Class<?>
mc space: 21832 [ 0,1% ] ... at 0x0000000800000000
rw space: 4093816 [ 22,2% ] ... at 0x0000000800006000
ro space: 7313320 [ 39,7% ] ... at 0x00000008003ee000
md space: 6352 [ 0,0% ] ... at 0x0000000800ae8000
od space: 6462536 [ 35,1% ] ... at 0x0000000800aea000
st0 space: 458752 [ 2,5% ] ... at 0x00000000fff00000
oa0 space: 65536 [ 0,4% ] ... at 0x00000000ffe00000
total : 18422144 [100.0% ] // JAVA_HOME/lib/server/classes.jsa
package io.simonis;
public class HelloCDS {
public static void main(String[] args) throws IOException {
System.out.println("Hello CDS");
System.in.read();
}
}
$ java -Xshare:on io.simonis.HelloCDS
HelloCDS
$ java -Xshare:on -Xlog:class+load io.simonis.HelloCDS
[class,load] java.lang.Object source: shared objects file
...
[class,load] j.i.l.URLClassPath$FileLoader source: jrt:/java.base
...
[class,load] io.simonis.HelloCDS2 source: file:/examples/bin/
HelloCDS
$ java -Xshare:on -Xlog:class+load io.simonis.HelloCDS \
| grep "shared objects file" | wc
477 2862 40977
$ java -Xshare:on -Xlog:class+load io.simonis.HelloCDS \
| grep -v "shared objects file" | wc
5 17 424
$ time -f "%e sec\n" java -Xshare:off io.simonis.HelloCDS
Hello CDS
0.162 sec
$ time -f "%e sec\n" java -Xshare:on io.simonis.HelloCDS
Hello CDS
0.148 sec
About 9% overall performance improvement
$ java -Xshare:off -Xlog:class+load io.simonis.HelloCDS
[0,164s][class,load] io.simonis.HelloCDS source: file:/examples/bin
$ java -Xshare:on -Xlog:class+load io.simonis.HelloCDS
[0,143s][class,load] io.simonis.HelloCDS source: file:/examples/bin
Application class loads about 13% faster
$ java -Xshare:on io.simonis.HelloCDS &
HelloCDS
$ pmap -X `pgrep -f HelloCDS`
5707: /jdk/bin/java -Xshare:auto io.simonis.HelloCDS
Address Perm Size Rss Pss Mapping
00400000 r-xp 8 8 8 /jdk/bin/java
00601000 r--p 4 4 4 /jdk/bin/java
00602000 rw-p 4 4 4 /jdk/bin/java
009b8000 rw-p 132 28 28 [heap]
83200000 rw-p 129024 2048 2048 // mapped Java heap
8b000000 ---p 1914880 0 0 // unmapped Java heap
ffe00000 rw-p 64 64 64 /jdk/lib/server/classes.jsa
fff00000 rw-p 448 448 448 /jdk/lib/server/classes.jsa
800000000 rwxp 24 24 24 /jdk/lib/server/classes.jsa
800006000 rw-p 4000 3168 3168 /jdk/lib/server/classes.jsa
8003ee000 r--p 7144 5160 5160 /jdk/lib/server/classes.jsa
800ae8000 rw-p 8 8 8 /jdk/lib/server/classes.jsa
800aea000 r--p 6312 0 0 /jdk/lib/server/classes.jsa
$ CATALINA_OPTS="-Xshare:on \
-Xlog:class+load:file=/tmp/tomcat.classtrace" \
catalina.sh start
$ wc /tmp/tomcat.classtrace
12644 50575 2075264 /tmp/tomcat.classtrace
$ grep "shared objects file" /tmp/tomcat.classtrace | wc
1156 6936 103052
$ CATALINA_OPTS="-XX:DumpLoadedClassList=/tmp/tomcat.cls" \
catalina.sh start
$ wc /tmp/tomcat.cls
3261 3261 125647 /tmp/tomcat.cls
$ CATALINA_OPTS="-XX:DumpLoadedClassList=/tmp/tomcat_appcds.cls \
-XX:+UseAppCDS" \
catalina.sh start
$ wc /tmp/tomcat_appcds.cls
3520 3520 133431 /tmp/tomcat_appcds.cls
$ CATALINA_OPTS="-Xshare:dump -XX:+UseAppCDS \
-XX:SharedClassListFile=/tmp/tomcat_appcds.cls \
-XX:+UnlockDiagnosticVMOptions \
-XX:SharedArchiveFile=/tmp/tomcat_appcds.jsa" \
catalina.sh start
$ ll /tmp/tomcat_appcds.jsa
-r--r----- 49.979.392 Feb 2 23:57 /tmp/tomcat_appcds.jsa
$ CATALINA_OPTS="-Xshare:on -XX:+UseAppCDS \
-XX:+UnlockDiagnosticVMOptions \
-XX:SharedArchiveFile=/tmp/tomcat_appcds.jsa" \
catalina.sh start
-XX:+UseAppCDS
-XX:DumpLoadedClassList=.. -XX:+UseAppCDS
-XX:DumpLoadedClassList=...
creates a trivial class list:
$ cat /tmp/tomcat_appcds.cls
java/lang/Object
java/lang/String
...
org/apache/catalina/startup/Bootstrap
CLASSNAME [ ID ]?
CLASSNAME ID super: ID [ interface: [ ID ]+ ]? source: URL
-Xlog:class+load=debug
has all we need:
$ CATALINA_OPTS="-Xlog:class+load=debug" catalina.sh start
[..] java.lang.Object source: jrt:/java.base
[..] klass: 0x100000eb0 super: 0x000000000 loader: [NULL class loader]
....
[..] java.sql.Timestamp source: jrt:/java.sql
[..] klass: 0x100096c30 super: 0x100091a00 \
loader: [0xff0172600 a 'ClassLoaders$PlatformClassLoader']
....
[..] org.apache.catalina.Server source: file:catalina.jar
[..] klass: 0x1000e6410 super: 0x100000eb0 interfaces: 0x1000e6238 \
loader: [0xff0310fb0 a 'java/net/URLClassLoader']
java/lang/Object id: 0x100000eb0
java/sql/Timestamp id: 0x100096c30
org/apache/catalina/Server id: 0x1000e6410 super: 0x100000eb0 \
interfaces: 0x1000e6238 source: catalina.jar
cl4cds
cl4cds
converts a class log to a CDS class list:
$ CATALINA_OPTS="-Xlog:class+load=debug:file=tomcat_dbg.clstrace" \
catalina.sh start
$ java io.simonis.cl4cds tomcat_dbg.clstrace tomcat_cl4cds.cls
$ CATALINA_OPTS="-Xshare:dump -XX:+UseAppCDS \
-XX:SharedClassListFile=tomcat_cl4cds.cls \
-XX:+UnlockDiagnosticVMOptions \
-XX:SharedArchiveFile=tomcat_cl4cds.jsa" \
catalina.sh start
$ ll tomcat_cl4cds.jsa
-r--r----- 1 102.305.792 Feb 3 01:48 tomcat_cl4cds.jsa
$ CATALINA_OPTS="-Xshare:on -XX:+UseAppCDS \
-XX:+UnlockDiagnosticVMOptions \
-XX:SharedArchiveFile=tomcat_cl4cds.jsa \
-Xlog:class+load:file=tomcat_cl4cds.clstrace" \
catalina.sh start
$ wc tomcat_cl4cds.clstrace
12644 69335 1531203 tomcat_cl4cds.clstrace
$ grep "shared objects " tomcat_cl4cds.clstrace | wc
9380 56280 963418