Shenandoah 靠一组屏障让回收和应用线程并发。每种模式到底开了哪些屏障?能单独关掉吗?它们在读写引用时到底有多贵?这篇逐项检查、逐项测量。
JDK 21 satb SATB=true IU=false LoadRef=true CAS=true Clone=true StackWatermark=true
JDK 21 iu SATB=false IU=true LoadRef=true CAS=true Clone=true StackWatermark=true
JDK 21 passive SATB=false IU=false LoadRef=false CAS=false Clone=false StackWatermark=false
JDK 27 satb SATB=true LoadRef=true Clone=true Card=false
JDK 27 generational SATB=true LoadRef=true Clone=true Card=true
JDK 27 passive SATB=false LoadRef=false Clone=false Card=false
关闭任一屏障(satb 模式):每个都被拒绝(见 JDK 21 与 27 上的错误信息):
JDK 21 -XX:-ShenandoahSATBBarrier → Error: GC mode needs -XX:+ShenandoahSATBBarrier to work correctly
JDK 21 -XX:-ShenandoahLoadRefBarrier → Error: GC mode needs -XX:+ShenandoahLoadRefBarrier to work correctly
JDK 27 -XX:-ShenandoahSATBBarrier → Error: GC mode needs -XX:+ShenandoahSATBBarrier to work correctly
JDK 27 -XX:-ShenandoahLoadRefBarrier → Error: GC mode needs -XX:+ShenandoahLoadRefBarrier to work correctlyJDK 21 satb 链表读 57.63 ns/节点 引用存储 1.74 ns/次 (读 [56.58, 64.67, 57.63] 存 [1.74, 1.74, 1.74]) JDK 21 iu 链表读 58.64 ns/节点 引用存储 1.64 ns/次 (读 [58.64, 59.73, 56.5] 存 [1.64, 1.64, 1.64]) JDK 21 passive 链表读 57.5 ns/节点 引用存储 1.48 ns/次 (读 [56.28, 58.28, 57.5] 存 [1.49, 1.46, 1.48]) JDK 27 satb 链表读 57.31 ns/节点 引用存储 1.34 ns/次 (读 [57.2, 57.67, 57.31] 存 [1.33, 1.34, 1.37]) JDK 27 generational 链表读 58.32 ns/节点 引用存储 1.49 ns/次 (读 [58.39, 58.32, 57.29] 存 [1.49, 1.49, 1.51]) JDK 27 passive 链表读 57.73 ns/节点 引用存储 1.34 ns/次 (读 [58.64, 57.73, 56.72] 存 [1.34, 1.32, 1.35]) JDK 21 G1(对照) 链表读 57.55 ns/节点 引用存储 3.22 ns/次 (读 [62.38, 57.55, 56.37] 存 [4.36, 3.22, 3.05]) JDK 27 G1(对照) 链表读 56.41 ns/节点 引用存储 1.66 ns/次 (读 [59.62, 56.41, 55.72] 存 [1.66, 1.67, 1.64])
JDK 21 satb 暂停 984 次;Final Mark 246 次 最大 0.334 ms;Final Update Refs 246 次 最大 0.036 ms;Init Mark 246 次 最大 0.073 ms;Init Update Refs 246 次 最大 0.008 ms;6 秒分配 9.7 百万次 JDK 21 iu 暂停 1008 次;Final Mark 252 次 最大 0.231 ms;Final Update Refs 252 次 最大 0.030 ms;Init Mark 252 次 最大 0.080 ms;Init Update Refs 252 次 最大 0.030 ms;6 秒分配 10.0 百万次 JDK 27 satb 暂停 570 次;Final Mark 99 次 最大 0.361 ms;Final Update Refs 52 次 最大 0.064 ms;Init Mark 419 次 最大 0.038 ms;6 秒分配 24.0 百万次 JDK 27 generational 暂停 468 次;Final Mark 118 次 最大 0.185 ms;Final Update Refs 89 次 最大 0.075 ms;Init Mark 261 次 最大 0.029 ms;6 秒分配 18.8 百万次