jvm垃圾回收器演进是对停顿时间、吞吐量、内存占用的持续权衡:分代设计基于对象生命周期假说;cms以并发标记换取低延迟但产生碎片;g1通过分区与垃圾密度优先实现可预测停顿;zgc和shenandoah借助染色指针或brooks指针达成毫秒级stw。

JVM 垃圾回收器的演进不是技术堆砌,而是对“停顿时间、吞吐量、内存 footprint”三者权衡的持续优化。每一次重大升级,都源于硬件能力提升与应用场景变化带来的新约束——单核时代追求简单可靠,多核时代转向吞吐优先,云原生和实时系统则倒逼亚毫秒级响应。
分代设计:基于对象生命周期的朴素洞察
早期 JVM 发现 98% 的对象“朝生夕死”,而少数存活对象往往长期驻留。这一观察催生了分代假说(Weak Generational Hypothesis),并直接指导内存划分为新生代(Eden + Survivor)和老年代。新生代用复制算法——只搬存活对象,快且无碎片;老年代用标记-整理或标记-清除——牺牲部分速度换取空间连续性。Serial 和 Parallel GC 都建立在此范式之上,区别仅在于是否多线程执行。
并发化突破:CMS 的尝试与代价
CMS(Concurrent Mark-Sweep)首次将“并发”引入老年代回收:标记阶段与用户线程并行运行,大幅压缩 STW 时间。但它依赖标记-清除算法,不整理内存,导致碎片累积;一旦触发 Full GC,退化为 Serial Old,停顿陡增。它本质上是“用 CPU 换时间”的妥协方案,适合对延迟敏感但堆不大、对象晋升率可控的场景。它的衰落不因缺陷本身,而因 G1 提供了更可控的替代路径。
分区化重构:G1 的可预测性革命
G1 放弃固定代际边界,把堆切分为多个大小相等的 Region(1–32MB),每个 Region 可动态扮演 Eden、Survivor 或 Old 角色。它不再按“代”回收,而是按“垃圾密度”回收——每次选垃圾最多的若干 Region 组成回收集(Collection Set)。通过 -XX:MaxGCPauseMillis 参数设定目标停顿,JVM 自动调节回收范围与频率。这使 GC 行为从“不可控”变为“可协商”,成为 JDK 9 起的默认回收器。
染色指针与元数据下沉:ZGC 和 Shenandoah 的底层跃迁
ZGC 和 Shenandoah 不再依赖 Stop-The-World 完成关键阶段。ZGC 使用染色指针(Colored Pointers),把对象标记位直接编码进 64 位地址的高几位;Shenandoah 则用 Brooks Pointer 在对象头前插入转发指针。二者都让标记、转移、重映射等操作可在应用线程运行时并发完成。结果是:无论堆大小是 4GB 还是 16TB,STW 时间稳定在 10ms 以内。这不是参数调优的结果,而是内存管理模型的根本重写。
不复杂但容易忽略











