Shenandoah 靠并发整理避免长暂停。日志里的停顿真的是应用感受到的停顿吗?这篇用同一个程序和 G1、ZGC 篇相同的负载比较日志停顿与程序实际看到的间隔(ZGC 一篇里同样的负载见前一篇)。
配置 存活集 日志最长停顿(ms) 程序看到的最长间隔(ms) >5 ms 间隔次数 循环次数 Degenerated Full G1 -Xmx2g ≈40 MB 6.94 7.00 20 1160872 0 0 G1 -Xmx2g ≈400 MB 88.73 94.54 71 242052 0 6 Shenandoah -Xmx2g ≈40 MB 0.17 15.16 48 1102631 0 0 Shenandoah -Xmx2g ≈400 MB 0.20 26.34 188 225865 0 0 Shenandoah -Xmx1g ≈40 MB 0.16 15.04 106 906581 0 0 Shenandoah -Xmx1g ≈400 MB 0.21 30.08 337 71256 0 0
Trigger: Learning 1 of 5. Free (1430M) is below initial threshold (1433M) GC(0) Concurrent reset 0.143ms GC(0) Pause Init Mark (unload classes) 0.088ms GC(0) Concurrent marking roots 0.102ms GC(0) Concurrent marking (unload classes) 82.898ms GC(0) Pause Final Mark (unload classes) 0.123ms GC(0) Concurrent thread roots 0.046ms GC(0) Concurrent weak references 0.023ms GC(0) Concurrent weak roots 0.076ms GC(0) Concurrent cleanup 718M->718M(2048M) 0.009ms GC(0) Concurrent class unloading 0.119ms GC(0) Concurrent strong roots 0.017ms GC(0) Concurrent evacuation 2.153ms GC(0) Pause Init Update Refs 0.011ms
ShenandoahGCHeuristics = adaptive ShenandoahGCMode = satb