在 JDK 21 上用真实的 jstack 命令读线程转储:BLOCKED / WAITING (on object monitor) / WAITING (parking) / TIMED_WAITING 各自的栈写法;jstack -l 的 Locked ownable synchronizers(189 → 249 行);用 cpu= 差值找 100% CPU 的线程;死锁段落(synchronized 与 ReentrantLock 各一对,不加 -l 也检测到两对);虚拟线程 jstack 看不到(0 个),Thread.dump_to_file 能。
在 JDK 21 上用 jcmd 逐个调用:help 列出 49 个命令;VM.set_flag 只能改 13 个 manageable 参数(MinHeapFreeRatio 40 → 55,MaxHeapSize 被拒绝);GC.run 把 used 32 MB 降到 1 MB;NMT 的 baseline / summary.diff 看到 100 MB 直接内存在 Other 里 +102400KB;JFR.start / dump / stop 的一次完整录制。
在 JDK 21 上实测 jmap:-histo 含 300 万个不可达对象(6645923 个 / 387 MB),-histo:live 先 Full GC 后只剩 631197 个;-dump 454.1 MB 对 -dump:live 137.2 MB,应用最大停顿 263 ms 对 43 ms;相对路径相对于 jmap 的工作目录;-heap 在 JDK 21 上不能用;jcmd GC.heap_dump 默认就是 live,与 jmap 默认相反。
在 JDK 21 / macOS 上实测 jhsdb:jstack --pid 给出死锁与带 @bci、Compiled/Interpreted 标注的栈;jhsdb 退出后目标进程仍处于 T(停住)状态,jcmd 无响应,手工 SIGCONT 后心跳最大间隔 12247 ms;jmap --histo 比 jmap -histo 慢约 30 倍;clhsdb 的 universe / threads;core 文件(3349 MB)用 jhsdb --core 读取失败。
在 JDK 21 上验证 java.time.Clock:fixed / offset / tick 的行为与 tick 的时长限制;注入 Clock 的过期测试 3.38 ms 对真实时钟 sleep 的 1254 ms;LocalDate.now() 与 Clock.fixed(…, systemDefault) 随默认时区而变;macOS 上 Instant.now() 是微秒分辨率;tickSeconds / tick(100 ms) 的取整;模拟时钟回拨时 Clock 差值为负。
在 JDK 17/21/27 上验证 ZoneRules:纽约 2026 年夏令时的空洞(0 个有效偏移)与重叠(2 个);一天是 23 / 24 / 25 小时,plusDays 与 plus(Duration.ofHours(24)) 差一小时;Asia/Shanghai 的历史偏移(+08:05:43、1988 年夏令时);New_York 177 条显式转换 + 2 条重复规则;三个 JDK 的 tzdata 都是 2026b;ZoneId.of 对 EST、大小写、空格的处理。
在 JDK 21 上验证 TemporalAdjuster:内置 next / nextOrSame / firstInMonth 等的结果与含不含当天;dayOfWeekInMonth(5 / 0 / -5) 在只有 4 个星期五的月份溢出到相邻月份;自写 NEXT_WORKING_DAY 与手写循环逐天比对 4018 天零不一致;适用于 LocalDate / ZonedDateTime / 泰佛历等,但对 YearMonth、LocalTime、Instant 抛异常;与夏令时空洞的交互。
在 JDK 21 上验证 MessageFormat:六个 Locale 下数字与日期的差别;整数 2026 变成 “2,026”;单引号会吞掉后面的占位符;ChoiceFormat 做复数的区间与边界,以及对俄语 101、102、1001 给出错误形式;参数不够时占位符原样保留;8 线程共用一个实例 16 万次里 80146 次结果错误并抛异常;静态 format 约 1.1 µs,复用实例约 0.32 µs。
在 JDK 21 上验证 DecimalFormat:模式语法;默认 HALF_EVEN 与 double 的二进制误差(1.005 → 1.00,BigDecimal 得 1.01);parse(“12abc”) 返回 12 不抛异常;Locale 错位解析 “1.234”(de_DE 得 1234);紧凑数字格式;8 线程共用实例 format 四种输入 0 次出错,但 parse 80 万次里 29 万次结果错误并抛异常,并发改设置出现乱码。
在 JDK 21 上验证 ResourceBundle:候选 Locale 列表(zh-CN 会先试 zh_CN_#Hans);默认 Locale 插进回退链(默认 fr 时请求 en 得到 français,NO_FALLBACK 才得到根);properties 读取默认 UTF-8 并在遇到非法字节时按 Latin-1 重读,但 0xE9 恰在文件末尾时抛 MissingResourceException;类 bundle 压过同名 properties;缓存默认永不过期,改文件不生效,需要 clearCache 或自定义 Control。
在 JDK 21 / macOS 上实测 Files.walkFileTree:回调顺序与目录顺序(不是字母序也不是创建序);SKIP_SUBTREE / SKIP_SIBLINGS / TERMINATE 在 pre 与 file 中返回的不同效果;maxDepth 到达上限的目录走 visitFile;递归删除;符号链接与 FileSystemLoopException;权限错误下 visitFileFailed 与 Files.walk 的 UncheckedIOException;4000 个文件的耗时对比。
在 JDK 21 / macOS 上实测 PathMatcher:21 个 glob 对 12 个路径的匹配矩阵;**/*.java 不匹配顶层文件、[^A-M] 不是取反、glob 区分大小写即使文件系统不区分;转义与分隔符;非法 pattern 的异常与不报错的 {}、***;newDirectoryStream 的 glob 只看一层,walk + PathMatcher 在相对路径与绝对路径下的结果。