并行gc造成短时高负载总线争用,并发gc引发持续性缓存一致性开销;前者表现为内存带宽峰值达85%以上、集中在100–500ms,后者维持15–25%带宽但持续数秒,并伴随写屏障导致的跨核缓存同步风暴。

并行垃圾回收和并发垃圾回收在多核处理器调度上的总线负载差异,核心不在“是否用多核”,而在“GC线程与用户线程是否共用同一套资源调度路径”——尤其是内存总线(Memory Bus)和缓存一致性协议(如MESI)的争用强度。
并行GC:高密度、短时爆发式总线争用
并行GC(如Parallel Scavenge + Parallel Old)启用多个GC线程,但所有用户线程全程STW。此时:
- 所有GC线程集中扫描、复制、整理堆内存,频繁访问大块连续对象区域,引发大量L3缓存失效和跨核缓存同步请求;
- 由于用户线程暂停,无应用级内存分配或引用更新,总线流量集中在GC内部数据搬运(如From-Space→To-Space复制),呈现“脉冲式峰值”;
- 多个GC线程竞争同一内存控制器带宽,尤其在老年代压缩阶段,需反复读写对象头、重定位指针,加剧DDR通道拥塞;
- 实际观测中,在32核服务器上运行Parallel Old时,内存带宽占用常达峰值85%以上,且集中在GC周期内100–500ms窗口。
并发GC:低强度、持续性总线渗透
并发GC(如G1的并发标记、CMS初始标记/并发预清理、ZGC的并发标记与转移)允许用户线程与GC线程交替或同时运行:
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
- GC线程以低优先级、分片方式执行任务(如G1按Region轮询、ZGC按页粒度扫描),内存访问离散、不连续,总线压力平缓;
- 但用户线程持续分配对象、更新引用(尤其是写屏障触发的卡表/记忆集更新),导致缓存行频繁失效、跨核缓存同步请求持续发生;
- 写屏障(Write Barrier)本身会插入额外指令,每次对象字段赋值都可能触发store-load序列,增加内存屏障开销和总线监听流量;
- 实测显示:G1在并发标记阶段,内存带宽占用仅维持在15–25%,但持续数秒甚至数十秒,总线处于“长尾低载+高频握手”状态。
关键区别不在吞吐,而在争用模式
二者对总线的影响本质不同:
- 并行GC是“高水位堰塞”:总线被GC独占压满,但时间短;用户线程不参与,无协同开销;
- 并发GC是“毛细血管渗漏”:总线未被压满,但GC与用户线程共享缓存、TLB、内存控制器,写屏障和并发修改引发大量缓存一致性消息(Invalidate/Ack),显著抬升QPI/UPI链路负载;
- 在NUMA架构下,并行GC倾向绑定本地节点内存操作,总线争用局限在单NUMA域;而并发GC中用户线程可能跨节点分配,GC线程又需远程拉取记忆集,加剧跨节点总线流量。
调优提示:看指标,别只盯停顿
判断总线瓶颈不能只看GC pause时间:
- 查perf stat -e cycles,instructions,cache-misses,mem-loads,mem-stores,对比并行/并发模式下cache-miss率与mem-store延迟变化;
- 用pcm-memory.x工具观察各socket的内存控制器读写带宽占比及QPI/UPI利用率;
- 若并发GC下STW时间短但应用RT毛刺增多,大概率是总线一致性风暴(如大量Invalidates阻塞store指令),而非CPU算力不足。










