shenandoah通过brooks转发指针实现全并发evacuation,取消分代模型并采用读写双屏障,使stw时间稳定控制在5ms以内;g1则因evacuation必须stw且保留分代设计,停顿波动大,通常达100–200ms。

因为Shenandoah把原本需要Stop-the-World(STW)的关键阶段,几乎全部搬到了与用户线程并发执行的路径上;而G1虽然也支持并发标记等环节,但核心的Evacuation(对象复制/转移)仍需STW。
关键差异:Evacuation是否STW
G1的Mixed GC或Full GC中,Evacuation阶段必须STW——即暂停所有应用线程,将存活对象从源Region复制到目标Region。这部分停顿常占整个GC停顿的80%以上,尤其在老年代回收压力大时明显。
Shenandoah则通过Brooks转发指针(Forwarding Pointer)技术,让对象移动过程完全并发:用户线程访问对象时,若发现已被标记为“待移动”,会自动跳转到新地址并协助更新引用;GC线程与应用线程互不阻塞。
内存管理模型更彻底去分代
G1保留分代逻辑(Eden/Survivor/Old Region),年轻代回收仍依赖STW的Minor GC;老年代回收虽引入并发标记,但整理阶段仍受限于区域间引用处理和部分STW操作。
Shenandoah默认取消分代设计,整堆统一视为Region集合,所有回收动作(标记、转移、引用更新、清理)均按并发策略调度,没有“必须等用户线程停摆才能开始”的硬性阶段。
屏障机制与开销权衡更偏向并发优先
G1使用SATB写屏障,主要服务于并发标记的快照一致性,但无法支撑并发转移;它仍需在Final Mark等环节做STW来清空缓冲区。
Shenandoah采用读写双屏障 + Brooks指针,在每次对象访问和字段更新时介入,代价是轻微的运行时开销,换来的是:
• 不再需要Final Mark阶段的STW
• 跨Region引用更新可全程并发完成
• 压缩(Compact)不再依赖停顿窗口
实际效果:STW时间大幅压缩
G1的目标停顿时间通常设为100–200ms(可通过-XX:MaxGCPauseMillis调控),但实际波动大,尤其在大堆或高分配率场景下易突破。
Shenandoah在JDK 17+稳定版本中,典型STW时间稳定控制在5ms以内,且基本与堆大小无关——这正是其“更激进”并发设计的直接体现:不是“部分并发”,而是“尽可能消灭STW”。











