Java垃圾回收的五十年——从标记清除到ZGC的演进之路

简介: 垃圾回收是Java平台的标志性特性,也是无数开发者选择Java而非C++的重要原因。

垃圾回收是Java平台的标志性特性,也是无数开发者选择Java而非C++的重要原因。从JDK 1.0到JDK 21,Java的垃圾回收算法经历了翻天覆地的变化,每一次演进都在吞吐量、延迟和内存占用之间寻找新的平衡。理解不同垃圾回收器的特点和工作原理,对于调优Java应用性能至关重要。
参考:https://xbivx.cn/category/provincial-forecast.html

标记-清除算法是最基础的垃圾回收算法。它分为两个阶段:标记阶段遍历所有存活对象,清除阶段回收未被标记的对象。这种算法的缺点是产生内存碎片,以及暂停时间与堆大小成正比。标记-清除的变种——标记-复制算法将内存分为两个半区,每次只使用其中一个,回收时将存活对象复制到另一个半区,然后清空原半区。复制算法无碎片,但内存利用率低。标记-整理算法在标记之后将存活对象向一端移动,然后清理边界以外的内存,既消除了碎片,又提高了内存利用率,但移动对象的开销较大。

分代假说是Java垃圾回收设计的理论基础。该假说指出:大部分对象朝生夕灭(年轻代),而老年代中的对象则长期存活。基于这个假说,JVM将堆内存分为年轻代和老年代。年轻代使用复制算法(因为大部分对象在GC中死亡),老年代使用标记-清除或标记-整理算法(因为存活率高,复制成本大)。

Serial GC是最古老的垃圾回收器,使用单线程进行垃圾回收。它会触发"Stop-The-World"暂停,所有应用线程停止,直到GC完成。Serial GC适合客户端应用或单处理器环境,堆内存较小(几十MB到几百MB)。它的优点是简单、内存占用低、没有线程同步开销。

Parallel GC(也称为吞吐量优先收集器)是JDK 8及之前版本的默认收集器。它使用多线程进行垃圾回收,充分利用多核CPU。Parallel GC的目标是最大化吞吐量(应用运行时间与总时间的比值)。它适用于后台处理、批处理等对暂停时间不敏感的场景。Parallel GC在年轻代使用并行复制,在老年代使用并行标记-整理。

CMS GC(Concurrent Mark Sweep)是第一款低延迟垃圾回收器。它的目标是减少暂停时间,将垃圾回收的大部分工作与应用线程并发执行。CMS的回收过程包括:初始标记(STW,标记GC Roots直接可达的对象)、并发标记(与应用线程一起标记所有存活对象)、重新标记(STW,处理并发标记期间发生变化的对象)、并发清除(清除未标记的对象)。CMS的缺点是产生内存碎片(因为不整理),且浮动垃圾(并发标记期间新产生的垃圾)需要等待下次GC。

G1 GC(Garbage First)在JDK 7u4中正式发布,在JDK 9中成为默认收集器。G1将堆内存划分为多个大小相等的Region,每个Region可以是年轻代或老年代。G1的回收策略是:优先回收垃圾最多的Region(Garbage First因此得名)。G1的目标是在可预测的暂停时间内回收尽可能多的内存。它使用停顿预测模型,动态调整年轻代大小和回收区域的数量。G1的回收过程包括:年轻代收集、并发标记周期、混合收集(逐步回收老年代Region)。G1避免了CMS的碎片问题,因为它在需要时对Region进行整理。
参考:https://xbivx.cn/category/national-weather.html

ZGC(Z Garbage Collector)在JDK 11中引入,在JDK 15中成为生产就绪。ZGC的目标是在任意堆大小(从几百MB到16TB)下,将暂停时间控制在10ms以内。ZGC使用读屏障和染色指针技术,将大部分GC工作与应用线程并发执行。ZGC的暂停只发生在根扫描阶段,且暂停时间不随堆大小增长。ZGC的设计挑战包括:处理大堆的并发标记和重定位、与操作系统内存管理的交互、以及JIT编译器的适配。ZGC适用于大堆内存、低延迟的场景,如金融交易系统、在线游戏服务器。

Shenandoah GC与ZGC类似,也是低延迟并发回收器,由Red Hat开发,在JDK 12中引入。与ZGC使用染色指针不同,Shenandoah使用 Brooks指针(转发指针)和读屏障实现并发压缩。Shenandoah的回收过程包括:初始标记、并发标记、并发清理、并发压缩等阶段。Shenandoah和ZGC代表了垃圾回收技术的前沿,它们将暂停时间从秒级降低到毫秒级甚至亚毫秒级。

Epsilon GC是JDK 11中引入的无操作垃圾回收器。它分配内存但不回收,当堆内存耗尽时JVM退出。Epsilon适用于短期任务、性能测试、或完全由应用管理内存的场景。

GC调优是Java性能工程的重要部分。调优的步骤包括:明确目标(吞吐量优先还是延迟优先)、监控GC日志(使用-Xlog:gc*)、选择合适的垃圾回收器、调整堆大小(-Xms和-Xmx)、调整年轻代与老年代比例(-XX:NewRatio)、调整晋升阈值(-XX:MaxTenuringThreshold)等。过度调优往往是反模式——在大多数情况下,默认配置已经足够好。

GC日志分析工具可以帮助理解GC行为。GCViewer、GCEasy、JMC等工具可以可视化GC事件,分析暂停时间、吞吐量、晋升速率等指标。现代JVM还提供了JFR(Java Flight Recorder)事件,可以低开销地采集GC信息。

未来趋势:Project Lilliput(JDK 21预览)尝试缩减对象头大小,减少内存占用;Project Valhalla的值类型将进一步减少对象数量,降低GC压力;分代ZGC(JDK 21正式)将年轻代和老年代分离,进一步提升ZGC的性能。

垃圾回收不是魔法,而是一套精心设计的算法和工程实现。理解GC的工作原理,不仅有助于调优,还能帮助开发者写出对GC友好的代码:避免对象晋升、避免大对象分配、使用对象池复用对象、以及及时释放引用。
参考:https://xbivx.cn

目录
相关文章
|
缓存 NoSQL Java
面试官:如何保证本地缓存的一致性?
面试官:如何保证本地缓存的一致性?
3299 1
|
6月前
|
人工智能 运维 云计算
我做了一个 Loki AI 事故分析引擎,已上架阿里云计算巢
后端开发者Luke打造Loki AI事故分析引擎,已上架阿里云计算巢!支持自动拉取Loki日志、调用Qwen/DeepSeek大模型智能根因分析,1-2分钟生成结构化报告(含根因、建议、时间线等),并推送至企微/钉钉。私有化部署,数据不出阿里云账号。
743 3
|
达摩院 Java 测试技术
最新迭代|FunASR离线文件转写软件包2.0
最新迭代|FunASR离线文件转写软件包2.0
1739 0
|
4月前
|
存储 算法 Java
【JVM虚拟机】垃圾回收GC:垃圾收集器:ZGC/Shenandoah:核心原理、低延迟特性、JDK21分代ZGC优化(2026超高频)(附《思维导图》+《面试高频考点清单》)
本文系统梳理ZGC与Shenandoah两大低延迟GC器的核心原理(着色指针/ Brooks指针、读屏障)、分代优化(JDK21+)、性能对比及调优实践,覆盖2026年面试超高频考点,助力秒答原理、设计与选型问题。
|
6月前
|
存储 算法 Java
Java的垃圾回收算法演进:从Serial到ZGC
Java的自动内存管理(垃圾回收,GC)是其区别于C++的重要特性之一。
487 3
|
12月前
|
存储 分布式计算 大数据
基于Python大数据的的电商用户行为分析系统
本系统基于Django、Scrapy与Hadoop技术,构建电商用户行为分析平台。通过爬取与处理海量用户数据,实现行为追踪、偏好分析与个性化推荐,助力企业提升营销精准度与用户体验,推动电商智能化发展。
|
6月前
|
人工智能 安全 API
闭眼入!2026 最新版 OpenClaw 中文版,一键安装零门槛(包含新安装包)
家人们,这款 2026 最新版 OpenClaw 一键安装包真的可以闭眼入!彻底告别复杂操作,不用懂编程、不用敲命令、不用查攻略,零门槛上手。内置完整中文汉化与运行环境,自动适配 Windows 全系列系统,下载后点几下鼠标就能装好,无捆绑、无广告、无报错,功能无删减,不管是新手还是老手,装完都能直接用,日常使用完全够用,闭眼冲不踩坑!
|
人工智能 供应链 API
2026:深度拆解智能体(Agent)重构西南制造的三重核心能力
2026年,中国制造业重心西移,西南工厂面临供应链与人力双重挑战。智能体(Agent)正以感知、推理、行动三位一体能力,推动生产从“经验驱动”迈向“自主决策”。它不仅是技术升级,更是认知革命——重构调度、工艺与供应链,实现毫秒响应、知识沉淀与跨域协同,打造高“认知密度”的未来工厂。
379 0

热门文章

最新文章