JVM垃圾回收器演进史:从单线程到亚毫秒停顿的探索之路

垃圾回收(Garbage Collection, GC)是Java生态的核心技术之一,其演进历程不仅反映了硬件性能的飞速发展,也映射了从桌面应用到云原生时代的场景变迁。本文将带你回顾JVM垃圾回收器的重要发展阶段,解析每个时代的关键技术及其背后的设计哲学。


一、单线程时代:Serial GC(JDK 1.3)

核心特点

  • 单线程回收:所有GC操作由单个线程执行,触发时暂停所有应用线程(Stop-The-World, STW)。

  • 分代模型

    • 年轻代:复制算法(存活对象从Eden区复制到Survivor区)
    • 老年代:标记-整理算法(Serial Old)
  • 适用场景:单核CPU、客户端应用(如早期Swing程序)。

历史意义

作为JVM最早的GC实现,Serial GC奠定了分代回收的基础逻辑,但其单线程模型在多核时代迅速暴露性能瓶颈。


二、并行化革命:Parallel GC(JDK 1.4~1.5)

1. Parallel Scavenge + Parallel Old

  • 目标:最大化吞吐量(单位时间处理任务量)。

  • 设计

    • 年轻代(Parallel Scavenge):多线程并行复制算法。
    • 老年代(Parallel Old,JDK 1.5引入):多线程标记-整理算法。
  • 适用场景:计算密集型任务(如离线数据分析)。

2. ParNew + CMS组合(JDK 1.5)

  • ParNew

    • 年轻代多线程回收器,专为CMS设计。
    • 与Parallel Scavenge类似,但优化方向不同(低延迟优先)。
  • CMS(Concurrent Mark-Sweep)

    • 老年代并发标记-清除,减少STW时间。
    • 局限性:内存碎片、并发失败时回退到Serial Old(长时间STW)。

技术突破

通过多线程并行化,显著提升吞吐量,但延迟问题(尤其是Full GC)仍未彻底解决。


三、分区时代:G1 GC(JDK 7u4~9)

核心设计

  • 堆分区:将堆划分为多个等大小的Region(区域),动态管理年轻代/老年代。
  • 回收策略:优先回收垃圾比例高的Region(Garbage-First),兼顾吞吐量和延迟。

优势

  • 可预测停顿 :通过-XX:MaxGCPauseMillis参数设定目标停顿时间。
  • 内存碎片控制:整体采用标记-整理算法,避免CMS的碎片问题。

历史地位

JDK 9起成为默认GC,取代CMS成为服务端应用的主流选择。


四、低延迟时代:ZGC与Shenandoah(JDK 11+)

1. ZGC(Z Garbage Collector)

  • 目标:亚毫秒级停顿,支持TB级堆内存。

  • 关键技术

    • 染色指针(Colored Pointers) :在指针中嵌入元数据,实现并发标记与压缩。
    • 读屏障(Load Barrier) :动态修正指针状态,无需全局暂停。
  • 适用场景:实时系统、云原生基础设施。

2. Shenandoah

  • 核心创新

    • 并发压缩:与ZGC类似,但通过Brooks指针实现内存整理。
    • 停顿时间与堆大小无关。
  • 与ZGC的区别

    • Shenandoah由Red Hat主导,ZGC由Oracle开发。
    • 实现细节不同(如内存屏障机制),但目标一致。

技术突破

通过并发压缩和硬件级优化(如多核并行),彻底打破"低延迟需牺牲吞吐量"的传统困局。


五、特殊用途回收器

1. Epsilon GC(JDK 11)

  • 特点:只分配内存,不执行回收。
  • 用途:性能测试、短生命周期任务(如CI/CD流水线)。

2. Serial Old的终局

  • 历史角色:CMS的备选回收器,单线程标记-整理。
  • 现状:随CMS在JDK 14中被移除,逐渐退出历史舞台。

六、演进驱动力与未来趋势

1. 核心驱动力

  • 硬件发展:多核CPU、大内存、NUMA架构。
  • 应用场景:从批处理到实时系统、微服务、Serverless。
  • 算法创新:并发标记、染色指针、读屏障等技术突破。

2. 未来方向

  • 异构计算:利用GPU/DPU加速GC任务。
  • 内存层级优化:针对持久化内存(PMEM)等新硬件设计GC策略。
  • 无分代模型:ZGC/Shenandoah已验证统一堆管理的可行性。

七、总结:如何选择垃圾回收器?

场景 推荐GC 关键参数
低延迟实时系统 ZGC/Shenandoah -XX:+UseZGC / -XX:+UseShenandoahGC
高吞吐批处理 Parallel GC -XX:+UseParallelGC
中小堆内存平衡场景 G1 GC -XX:+UseG1GC
短期任务/测试 Epsilon GC -XX:+UseEpsilonGC

八、演进时间线

年代 核心事件
2000s初 Serial GC(单线程分代)
2004 Parallel Scavenge + Serial Old(JDK 1.4)
2005 CMS + ParNew + Serial Old(JDK 1.5)
2012 G1 GC(实验性,JDK 7u4)
2017 G1成为默认(JDK 9)
2018~2020 ZGC/Shenandoah实验性引入(JDK 11~15)
2023+ ZGC成为生产环境主流(JDK 21+优化)

结语:JVM垃圾回收器的演进是一部"与硬件赛跑,为应用赋能"的技术史诗。理解这段历史,不仅能帮助开发者优化系统性能,更能洞察未来技术的演进方向。正如Java始终"Write Once, Run Anywhere",GC技术也在不断追求"Pause Less, Serve More"的理想境界。

相关推荐
Victor35614 小时前
https://editor.csdn.net/md/?articleId=139321571&spm=1011.2415.3001.9698
后端
Victor35615 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
后端
灰子学技术16 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
Gogo81617 小时前
BigInt 与 Number 的爱恨情仇,为何大佬都劝你“能用 Number 就别用 BigInt”?
后端
fuquxiaoguang17 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析
毕设源码_廖学姐18 小时前
计算机毕业设计springboot招聘系统网站 基于SpringBoot的在线人才对接平台 SpringBoot驱动的智能求职与招聘服务网
spring boot·后端·课程设计
野犬寒鸦19 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
逍遥德20 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
MX_935921 小时前
Spring的bean工厂后处理器和Bean后处理器
java·后端·spring
小迷糊的学习记录21 小时前
0.1 + 0.2 不等于 0.3
前端·javascript·面试