用 mvn dependency:tree 解析 6 个直接依赖(13 个构件),再用 OSV 的 querybatch 在 2.7 秒内查出 11 个构件共 92 条已知漏洞记录(jackson-databind 2.9.8 一个就有 59 条);传递依赖里有 5 个构件带漏洞;各漏洞的 CVE、严重程度、修复版本;同一个库不同版本的记录数对比。
用 Maven 3.9 与 maven-build-cache-extension 1.2.0 在一个 8 个类加 1.5 秒测试的小项目上实测:增量编译在没改东西时不重新编译但仍跑测试(2.8 秒),改一个文件会重新编译整个模块的 8 个源文件;构建缓存命中后 clean verify 只要 1.2 秒(跳过编译、测试、打包 6 个插件执行),源文件改动后未命中 3.3 秒。
在 JDK 21 上逐个运行 MethodHandle 的组合器:insertArguments、dropArguments、filterArguments、filterReturnValue、permuteArguments、foldArguments、collectArguments、asSpreader、guardWithTest、catchException、tryFinally、countedLoop、asType、asVarargsCollector 的类型与结果,以及常见的类型错误;static final 句柄与直接调用一样快(0.58 ns),局部句柄 2.26 ns。
在 JDK 21 上验证 lambda 的实现:javac 把 lambda 体编成合成方法、使用处是 invokedynamic 加 LambdaMetafactory;非捕获 lambda 是单例、捕获的每次新建;第一个 lambda 链接 3.03 ms(-Xshare:off 时 6.42 ms);手动调用 metafactory 得到同类的隐藏类且调用耗时相同;可序列化 lambda 通过 altMetafactory 与 SerializedLambda。
在 JDK 21 上验证 ClassValue:每个 Class 一份缓存、computeValue 并发时被调用 8 次但只保留一个结果、取值 2.24 ns 比 ConcurrentHashMap 的 3.10 ns 更快;用自定义类加载器验证——static ConcurrentHashMap 与「值引用 key 的 WeakHashMap」会泄漏类加载器,ClassValue 即使值持有 Class 本身也不泄漏。
在 JDK 21 上对比同一份嵌套类源码 --release 21 与 --release 8 的编译结果:release 21 没有 access$ 桥接方法、有 NestHost / NestMembers 属性,类文件更少更小(3 个 2440 字节对 4 个 2696 字节);getNestHost / getNestMembers / isNestmateOf;反射读私有字段的限制;嵌套关系不一致时的 IllegalAccessError 与旧方式的 NoSuchMethodError。
在 JDK 21 上验证 assert:字节码里的 $assertionsDisabled 与 desiredAssertionStatus;-ea / -da / -esa 对不同包的作用;断言关闭时表达式不被求值;断言状态在类初始化时固定,之后再改无效;一个昂贵的断言开启后每次迭代 10.51 ns,关闭时 0.58 ns。
用真实的分别编译验证枚举 switch 的兼容性:javac 生成 Client$1 与 $SwitchMap$Color(按名字映射,每个常量 try/catch NoSuchFieldError);库新增、重排、删除、重命名枚举常量时,不重新编译的客户端各种 switch 写法的行为:新增常量走 default 或抛 MatchException,删除常量不失败,直接用 ordinal() 会出错。
用 -XX:+PrintInlining 在 JDK 21 上验证 JIT 内联:4 / 105 / 157 / 521 字节的方法在 C1 与 C2 两次编译中的内联决定(C2 内联 105 与 157 字节的,拒绝 521 字节的 hot method too big);改 FreqInlineSize 与 -Inline 的耗时;调用点接收者 1 / 2 / 3 / 4 种类型时 0.51 / 0.69 / 3.26 / 3.24 ns。
在 JDK 21 上验证 OSR:只被调用一次的 main 里的长循环,默认每迭代 0.7 ns,关闭 OSR 后停在解释器里 26 ns(与 -Xint 的 23.6 ns 相当);PrintCompilation 里带 % 与 @bci 的 OSR 记录经历 C1 → C2 → 作废 → 再 C1 → 再 C2 两轮;嵌套循环的 OSR 入口在内层循环头。
在 JDK 21 / 17 上验证元空间:300 个加载器 × 150 个类时 capacity 107.61 MB、used 98.10 MB,全部丢弃后 committed 从 106.92 MB 降到 3.82 MB;同样丢弃一半加载器,交错丢弃比丢弃前一半多留 32.79 MB 已提交的空闲 chunk(虚拟空间 committed 78.81 vs 55.50 MB);JDK 21 忽略 MetaspaceReclaimPolicy,JDK 17 的 none 丢弃后 committed 不降。
在 JDK 21 上复现类初始化死锁:A、B 互相引用的静态初始化器,以及 Parent 持有 Child 实例的无显式环的例子;两个线程都是 RUNNABLE,ThreadMXBean 的死锁检测返回 null,线程转储里看 “waiting on the Class initialization monitor”;时间窗口小于 1 ms 时 40/40 死锁,晚 5 ms 启动则 0/40。