类加载是启动时间的大头。CDS 把类的解析结果预先存进归档。这篇用一个真实的 Netty 应用测量默认 CDS 与 AppCDS 的效果、归档的创建方式,以及归档与类路径不一致时的各种表现。
默认(-Xshare:auto) 加载类 1581 个:来自 CDS 归档 937,jrt(JDK 模块文件)139,jar 文件 484,目录 0 -Xshare:off 加载类 1590 个:来自 CDS 归档 0,jrt(JDK 模块文件)1069,jar 文件 484,目录 0 响应首行:HTTP/1.1 200 OK
-Xshare:off 中位 145 ms(最小 144,最大 147) 默认 CDS(只有 JDK 类) 中位 122 ms(最小 119,最大 128) 应用类放在目录里(类路径上有一个 classes 目录)时创建动态归档:返回码 1,输出: ["[0.153s][error ][cds] Error: non-empty directory '<实验目录>'", 'Error occurred during initialization of VM'] ;归档文件是否生成: False 创建动态 AppCDS 归档:java -XX:ArchiveClassesAtExit=app.jsa(运行一次,退出时写归档),归档文件 5.6 MB,这次运行耗时 205 ms; AppCDS 动态归档 中位 68 ms(最小 67,最大 70) 使用 AppCDS 归档时:加载类 1578 个,来自 CDS 归档 1563 个(99%),其余来自 jar 2 个
touch 了类路径上的 netty-codec-http jar 的修改时间之后,-Xshare:auto 运行:返回码 0,时间 120 ms;输出:
This file is not the one used while building the shared archive file: <m2>/io/netty/netty-codec-http/4.1.115.Final/netty-codec-http-4.1.115.Final.jar
<m2>/io/netty/netty-codec-http/4.1.115.Final/netty-codec-http-4.1.115.Final.jar timestamp has changed.
[0.009s][warning][cds,dynamic] Unable to use shared archive. The top archive failed to load: <实验目录>
响应首行:HTTP/1.1 200 OK
同样条件 -Xshare:on:返回码 1;输出:
Unable to map shared spaces
Error occurred during initialization of VM
Unable to use shared archive.
类路径里库的顺序被调换后,-Xshare:auto 运行:返回码 0,来自 CDS 归档的类 937 / 1581;输出: ['shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)', '[0.009s][warning][cds,dynamic] Unable to use shared archive. The top archive failed to load: <实验目录>']第 1 次运行:200 ms,归档文件存在,大小 5.6 MB 第 2 次运行:70 ms,归档文件存在,大小 5.6 MB 第 3 次运行:69 ms,归档文件存在,大小 5.6 MB 第 4 次运行:68 ms,归档文件存在,大小 5.6 MB 之后再运行 3 次:[69, 70, 68] ms touch 了类路径上的一个库 jar 之后,第 1 次运行:154 ms touch 了类路径上的一个库 jar 之后,第 2 次运行:123 ms touch 了类路径上的一个库 jar 之后,第 3 次运行:120 ms 这 3 次运行之后,归档文件的修改时间是否变化: False 删除归档文件后再运行:201 ms,归档文件重新生成:True 再运行一次:69 ms