执行字节码时,JVM需要一些准备的工作。传类名,在磁盘上查找类,加载它,验证字节码,将类装载为自己的内部数据结构,每一步都需要花费一些时间,想想每次JVM都要加载成千上万个类,这时时间上的花费很明显可以看得出来。
因为Jar包并没有改变,class-data一直都是相同的,每次JVM执行的也是相同的查找,加载,验证动作。
AppCDS就是让类只做一次上述的验证,加载动作,然后将其打包,后续在运行相同的jar包时,直接从打包文件中读取类数据,或者当前同时运行的JVM实例直接共享一份相同的类数据。
- 不需要在进行复杂的类加载机制的每一步
- 多个JVM实例同时运行时,可以共享内存区
使用方式
使用APPCDS的完整步骤一般如下,不过现在JDK13简化了我们的操作,一般我不需要进行下面的所有步骤。
1 创建一个class的列表,让这些class可以被打包。
-XX:DumpLoadedClassList
复制代码
2 创建归档使用
-Xshare:dump -XX:SharedArchiveFile
复制代码
3 使用归档
-Xshare:on -XX:SharedArchiveFile
复制代码
归档系统类
创建归档
在JDK13中,系统内置的共享类以及被默认创建了,位于${JAVA_HOME}/lib/server
目录下
# 例如
ls /Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/lib/server
# 列出classes.jsa libjsig.dylib libjvm.dylib
复制代码
使用归档
打印类加载日志,查看日志文件中的信息,如果出现shared objects files
代表使用了appcds的归档文件。
**注意:**不是所有的类都会被共享,当前我们自定义的类仍然会走全部的类装载流程。
# 使用归档文件
/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -Xlog:class+load:file=cds.log -XX:SharedArchiveFile=jdk13.jsa -jar target/HelloApp.jar
# 不使用归档文件
/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -Xlog:class+load:file=nocds.log -Xshare:off -jar target/HelloApp.jar
复制代码
时间对比
明显看出来在使用归档之后用户态的时间缩短了一些,这次jar包,仅仅打印Hello World,没有做任何事情,如果在类增多的时候,效果就非常明细。
time /Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -XX:SharedArchiveFile=jdk13.jsa -jar target/HelloApp.jar
time /Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -Xshare:off -jar target/HelloApp.jar
复制代码
归档自定义类
其实JDK13已经默认帮我们把系统的类文件进行归档了,我们在使用的时候也不需要指定什么参数,默认-Xshare:on
。系统类的归档我们不需要关系太多,那么如何打包我们的应用类文件呢。
1 使用-XX:DumpLoadedClassList=classes.lst
查看当前JVM装载的类列表
2 使用-XX:SharedClassListFile=classes.lst
来指定那些类需要共享,以及指定-XX:SharedArchiveFile=app-cds.jsa
打包文件位置,这里不需要使用-jar来运行程序,指定jar包的位置即可。
/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -Xshare:dump -XX:SharedClassListFile=classes.lst -XX:SharedArchiveFile=jdk13-custom.jsa --class-path target/HelloApp.jar
复制代码
3 可以在JVM退出的时候,自动归档,使用选项-XX:ArchiveClassesAtExit=app-cds.jsa
4 使用归档文件
/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -XX:SharedArchiveFile=jdk13-custom.jsa -jar target/HelloApp.jar
复制代码
问题
有过有人更新了jar包的内容,共享类会怎么处理?
可以查看日志看一下,是否会加载修改后的类。-Xlog:class+load:file=cds.log
如果有任何问题,还是-Xlog:class+load:file=cds.log
看一下情况。
最后
JDK13中使用AppCDS的选项-XX:ArchiveClassesAtExit=${ARCHIVE}
,-XX:SharedArchiveFile=${ARCHIVE}