-xlog:class+load 是 jdk 9+ 和 jdk 8u261+ 唯一可靠启用类加载日志的方式,因 jdk 9 引入统一日志框架(jep 158),该功能被回溯至 jdk 8u261;旧版 jdk 8 不识别此参数,须用 -xx:+traceclassloading。

Java 8u261+ 和 Java 9+ 默认不输出类加载日志,-Xlog:class+load 是唯一可靠、开箱即用的启用方式;旧版 JDK 8(u261 之前)必须用 -XX:+TraceClassLoading,二者日志格式和开关粒度完全不同。
为什么 -Xlog:class+load 在 JDK 9+ 才有效
JDK 9 引入统一日志框架(JEP 158),-Xlog 取代了大量零散的 -XX:+* 开关。-Xlog:class+load 属于新日志子系统,JDK 8u261 是首个 backport 该功能的版本;更早的 JDK 8 会直接报错“Unrecognized VM option”。
- 错误现象:
Unrecognized VM option '-Xlog:class+load' - 验证方法:运行
java -version,确认是1.8.0_261或更高,或9+ - JDK 8u261 前只能退回到
-XX:+TraceClassLoading,但无法过滤、无时间戳、不显示 classloader 实例地址
-Xlog:class+load 的常用组合写法
单独用 -Xlog:class+load 输出量大且混杂,实际调试需叠加级别、输出目标和过滤条件。
- 只看加载成功(忽略失败):
-Xlog:class+load=info - 排除 bootstrap 类(减少干扰):
-Xlog:class+load=info:stdout:time,tags:level -Xlog:disable -Xlog:gc*:stdout(注意顺序,后置-Xlog:disable会关闭前面配置) - 输出到文件并滚动:
-Xlog:class+load=debug:file=/tmp/classload.log:time,uptime,level,tags:filecount=5,filesize=10M - 配合
-verbose:class对比:后者仅打印类名,前者带 classloader、地址、来源 jar 路径,信息更全
容易被忽略的 classloader 识别陷阱
日志里每行末尾的 [class, loader] 段落才是关键——相同类名但不同 classloader 会导致 NoClassDefFoundError 或 LinkageError,而 -Xlog:class+load 能暴露这个细节。
立即学习“Java免费学习笔记(深入)”;
- 常见误判:看到
Loaded java.lang.String就以为没问题,其实它可能来自jdk.internal.loader.ClassLoaders$AppClassLoader@12345678或org.springframework.boot.loader.LaunchedURLClassLoader@87654321 - 真正要盯的是 classloader 地址(如
@12345678)是否一致,而不是类名重复与否 - Spring Boot fat jar 场景下,
LaunchedURLClassLoader加载业务类,AppClassLoader加载依赖 jar 中的类,两者隔离——日志里会清晰体现
真正难的不是打开日志,而是从成百上千行输出里快速定位「谁在什么时候、用哪个 classloader、从哪加载了哪个类」。别依赖 grep 类名,先按 classloader 地址聚类,再看加载顺序和来源路径。










