新生代GC Minor Collection
在 JDK 21 的分代式 ZGC(Generational ZGC)中,Minor Collection 是专为高效回收年轻代(Young Generation)对象设计的垃圾回收过程。其核心目标是通过极低延迟(通常 <1ms)快速回收短期存活对象,避免影响应用线程,同时大幅降低 Allocation Stall(内存分配阻塞)风险。以下是其工作原理、技术实现及优化细节的全面解析:
🔄 一、Minor Collection 触发条件
- 年轻代空间不足: 当对象分配速率超过回收能力,年轻代 Region 耗尽时触发。
- 自适应预测机制: ZGC 实时监控分配速率,通过正态分布预测内存耗尽时间点,提前触发回收(避免被动阻塞)。
- 周期性触发:
若启用
XX:ZCollectionInterval参数,则按固定时间间隔强制执行,应对突发流量。
⚙️ 二、工作流程:并发标记与移动
Minor Collection 全程与用户线程并发执行,仅需极短同步停顿(两次 <1ms 的 STW)。流程分阶段如下:
阶段 1:Pause Mark Start(同步停顿)
- 目的:初始化标记,创建根集合(GC Roots)。
- 操作:
- 暂停所有应用线程(STW)。
- 扫描栈帧、静态变量等 GC Roots,标记直接可达的年轻代对象。
- 耗时:通常 ≤200μs(与堆大小无关)。
阶段 2:Concurrent Mark/Remap(并发标记与重映射)
- 目的:标记存活对象,并更新跨代引用。
- 操作:
- 并发标记:从 GC Roots 遍历对象图,标记所有存活对象(使用染色指针记录状态)。
- 维护 Remembered Set:
- Store Barrier 实时记录老年代指向年轻代的引用(跨代引用),避免全堆扫描。
- 通过卡表(Card Table) 标记存在跨代引用的内存页,Minor GC 仅需扫描这些页。
- 重映射:若对象已被移动(如上次 Major GC),Load Barrier 自动修正引用至新地址。主要是修复上一次gc之后,没有通过读屏障更新引用的引用。
- 特点:完全并发,无应用线程阻塞。
阶段 3:Pause Mark End(同步停顿)
- 目的:确认标记结果,准备对象移动。
- 操作:
- 短暂 STW,校验存活对象集合。
- 筛选待回收的 Region(死亡对象占比高的区域)。
- 耗时:≤200μs。
阶段 4:Concurrent Relocate(并发移动)
- 目的:将存活对象复制到新 Region,释放连续内存。
- 操作:
- 复制存活对象:
- 小型Region,死亡对象占比高的region存活对象复制至空闲年轻代 Region(或晋升至老年代)。
- 小型Region,死亡对象占比低的region不移动存活对象,只标记死亡对象的空间(将死亡对象空间加入空闲链表)
- 中型Region,与小型Region策略一致
- 大型Region,将region标记为清除,放回大型region的空闲链表
- 使用转发表(Forwarding Table) 记录新旧地址映射。
- 引用更新:
- Load Barrier 拦截对象访问,自动重定向至新地址(零复制感知)。
- 复制存活对象:
- 特点:移动过程并发,应用线程通过屏障无感切换对象地址。
🧩 三、核心技术:屏障与染色指针
分代 ZGC 通过以下技术实现并发回收与低延迟:
| 技术 | 作用 | 优化效果 |
|---|---|---|
| 染色指针 | 指针高 4 位存储对象状态(如存活、重定位标记)。 | 免去访问对象头,减少内存开销。 |
| Load Barrier | 读引用时移除元数据位,并修正过期指针(如对象移动后)。 | 实现对象移动的透明化,避免 STW。 |
| Store Barrier | 写引用时记录跨代指针到 Remembered Set,并标记对象存活。 | 解决跨代引用问题,避免扫描全堆。 |
| Remembered Set | 存储老年代→年轻代的跨代引用,通过卡表实现位图标记。 | Minor GC 仅扫描相关内存页,效率提升 10 倍+。 |
案例:京东压测显示,分代 ZGC 的 Remembered Set 使 Minor GC 耗时降低 85%,吞吐量提升 4 倍。
⚡ 四、性能优势与调优建议
1. 性能优势
- 低延迟:全程并发,STW 总时长 <1ms(TB 堆下仍稳定)。
- 高吞吐:针对性回收年轻代(90% 对象短期消亡),减少无效扫描。
- 无碎片:复制算法整理内存,避免老年代碎片导致的 Full GC。
2. 调优建议
-
启用分代模式:JDK 21 需显式开启:
-XX:+UseZGC -XX:+ZGenerational -
关键参数:
Xmx:唯一需手动设置的参数,建议为物理内存 60%~80%。XX:ZAllocationSpikeTolerance=2:降低值可提前触发 GC,避免阻塞(默认 2,敏感场景可设 1.5)。Xlog:gc*:启用详细日志,监控Allocation Stall频率。
-
避坑指南:
- 禁用传统参数(如
Xmn、XX:ConcGCThreads),分代 ZGC 自适应优化更高效。 - 升级配套组件:Spring Boot ≥2.7.18、Lombok ≥1.18.30。
- 禁用传统参数(如
💎 总结
Minor Collection 是分代 ZGC 的核心创新,通过并发标记、Remembered Set 精准管理跨代引用、读写屏障实现对象移动无感化,在亚毫秒级停顿下高效回收年轻代。其设计本质是以空间换确定性:通过额外内存维护元数据(如卡表、染色指针),换取极低延迟与高吞吐。生产实践表明,分代 ZGC 的 Minor Collection 可降低 Allocation Stall 达 85%,适用于电商秒杀、实时交易等内存敏感型场景。