JNI 里的数组临界区为什么会拖住整个 JVM 的垃圾回收?在新版本里还成立吗?这篇用一个 clang 编译的 JNI 函数持有临界区 600 ms,在 JDK 21 与 27、G1 与 Parallel 上各量一次(JNI 以外的堆外内存见前面的篇目)。
(JNI 方法是我用 clang 编译的 C 函数,usleep 模拟本地代码在临界区里的耗时) JDK / 回收器 临界区 (critical) 最长一次分配(ms) 分配次数 GC 次数 最长 GC 停顿(ms) JDK 21 G1 否(GetByteArrayElements 拷贝) 1.4 274165 2980 1.3 JDK 21 G1 是 610.1 164005 1782 0.5 JDK 21 Parallel 否(GetByteArrayElements 拷贝) 0.4 424006 3449 0.3 JDK 21 Parallel 是 592.4 181839 1473 1.0 JDK 27 G1 否(GetByteArrayElements 拷贝) 1.3 273446 2972 1.0 JDK 27 G1 是 0.6 274440 2983 0.5 JDK 27 Parallel 否(GetByteArrayElements 拷贝) 0.8 425288 3458 0.6 JDK 27 Parallel 是 604.0 254365 2068 0.4