bigywater.tech
Java · 165

Shenandoah:并发整理如何避免长暂停

Shenandoah 靠并发整理避免长暂停。日志里的停顿真的是应用感受到的停顿吗?这篇用同一个程序和 G1、ZGC 篇相同的负载比较日志停顿与程序实际看到的间隔(ZGC 一篇里同样的负载见前一篇)。

0.195 ms
Shenandoah(2 GB 堆,400 MB 存活集)日志里的最长停顿
26.34 ms
同一次运行里程序看到的最长间隔
0 / 0
退化回收与 Full GC 次数

日志里的停顿

实测 · 本机执行输出
配置                       存活集        日志最长停顿(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

分步演示

Shenandoah
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12(Homebrew 构建,支持 Shenandoah),-XX:+UseShenandoahGC;负载每组运行 6 秒
    • 没有验证:应用实际变慢的原因(可能是屏障或分配 pacing,本篇没有查)、ShenandoahGCMode 其它取值(iu、generational)、JDK 17 与 27 的 Shenandoah、更大的堆;所有数字来自一次运行
    京ICP备2026067502号-1京公网安备11010502063487号