当前位置: 首页 > news >正文

JVM 中的 GC 算法演进之路!(Serial、CMS、G1 到 ZGC)

引言

想象一下,Java 程序运行就像在一个巨大的图书馆里借书还书。这个图书馆(JVM 的内存堆区)为了高效运转,需要一个聪明的“图书管理员”来清理失效的书籍(垃圾对象)。这,就是垃圾回收器(GC)的使命!


一、什么是 GC?

GC(Garbage Collection)是 JVM 自动内存管理的重要组成部分,负责回收不再被引用的对象所占用的内存空间,防止内存泄露和内存溢出。

1.1 为什么需要 GC?

  • 自动内存管理,减轻开发者负担
  • 避免野指针、内存泄露等问题
  • 保证 Java 应用稳定高效运行

1.2 GC 面临的挑战

  • 如何在不打断业务的前提下进行垃圾回收?
  • 如何避免过多的 STW(Stop-The-World)?
  • 如何在高并发、大内存场景下依然稳定?

二、JVM 内存结构简析(理解 GC 的基础)

JVM 堆区被划分为以下几个区域:

  • 新生代(Young Generation):包括 Eden 和两个 Survivor 区
  • 老年代(Old Generation):存放长生命周期的对象
  • 元空间(Metaspace):替代原有的永久代,存放类的元数据

垃圾回收的重点主要在 新生代和老年代


三、GC 算法简述

Java GC 的核心算法主要有:

  • 复制算法(Copying):用于新生代
  • 标记-清除(Mark-Sweep):用于老年代
  • 标记-压缩(Mark-Compact):避免内存碎片
  • 分代收集理论:新生代频繁回收,老年代少回收

四、GC 发展史:从 Serial 到 ZGC

4.1 Serial GC(串行垃圾回收器)

  • 回收机制:新生代使用复制算法,老年代使用标记-压缩算法
  • 回收线程:单线程
  • 触发机制:内存耗尽或触发 Full GC 时
缺点
  • 每次 GC 都会 Stop-The-World,且只能使用单线程
示例
-XX:+UseSerialGC

📌 适用场景:嵌入式、小型应用、单核处理器


4.2 CMS GC(Concurrent Mark Sweep)

CMS 是第一个低延迟为目标的 GC,着眼于缩短老年代的 GC 停顿时间。

工作流程
初始标记(STW) → 并发标记 → 重新标记(STW) → 并发清除
特点
  • 多线程并发标记和清除,减少 STW
  • 使用 标记-清除 算法,导致内存碎片问题
示例参数
-XX:+UseConcMarkSweepGC
缺点
  • 并发失败风险:老年代空间不足时需退化为 Serial Old GC
  • 空间碎片影响分配性能

📌 适用场景:中大型系统,对响应时间敏感的 Web 应用


4.3 G1 GC(Garbage First)

G1 GC 是 JDK 9 之后的默认 GC,旨在取代 CMS。

原理
  • 将整个堆划分为多个大小一致的 Region(既可作为 Eden、Survivor、Old)
  • 基于 Region 的优先级回收策略:优先回收垃圾最多的 Region
  • 并发标记后,通过 Evacuation 将存活对象复制到新的 Region,实现压缩
回收流程
初始标记(STW) → 并发标记 → 最终标记(STW) → 筛选回收(STW)
特点
  • 支持大堆(数十 GB)
  • 可配置 Pause Time(停顿目标)
  • 减少 Full GC 的频率
示例参数
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200

📌 适用场景:中大型服务端应用,追求吞吐和响应时间平衡


4.4 ZGC(Z Garbage Collector)

ZGC 是一个为低延迟场景设计的 GC,目标是将所有 GC 停顿控制在 10ms 以内。

特点
  • 几乎全程并发执行,所有 GC 阶段都不长时间阻塞应用线程
  • 使用 染色指针(Colored Pointers) 来标识对象状态
  • 通过读屏障和写屏障实现引用更新的同步
技术亮点
  • 支持极大的堆内存(最高可达 TB 级)
  • 多阶段并发整理,移动对象时应用线程无需停止
示例参数
-XX:+UseZGC
-XX:+UnlockExperimentalVMOptions

📌 适用场景:金融、电商、游戏等低延迟业务


五、不同 GC 的对比总结

特性SerialCMSG1ZGC
停顿时间极低
并发回收
内存碎片
吞吐量
响应时间更好极佳
大内存支持一般极好
是否压缩整理

六、GC 日志分析建议

可以通过以下 JVM 参数输出 GC 日志:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log

常见指标:

  • GC time:单次回收的耗时
  • freed memory:回收掉的内存大小
  • pause time:STW 的具体时间

七、真实案例分析

场景:大数据系统使用 CMS 导致频繁 Full GC

问题: CMS 回收速度跟不上对象创建速度,频繁触发 Full GC,导致延迟剧增。

解决方案: 切换为 G1 GC,并设置合理的 MaxGCPauseMillis,显著降低了延迟峰值。


八、选择建议

应用场景推荐 GC
单线程、小型程序Serial
中等延迟要求CMS
大型服务端系统G1
超大堆、极低延迟ZGC / Shenandoah

九、总结与未来展望

JVM 垃圾回收技术不断进化,从最初的串行单线程到如今几乎无感知的并发收集器,反映了 Java 在现代应用场景下对性能、可伸缩性和稳定性的持续追求。

未来,ZGC 与 Shenandoah 的持续优化将成为主流趋势,也许某一天,GC 将真正做到“零成本”!


🔚 尾声

👍 点赞 + ⭐ 收藏,助你 GC 不迷路!
📬 评论聊聊你在使用 GC 中踩过的坑,或者你的调优秘籍~
📌 关注我,带你一起玩转 Java 性能调优!

http://www.lryc.cn/news/575063.html

相关文章:

  • 7.Spring框架
  • 【机器人编程基础】Python模块的定义和导入
  • 融合聚类与分类的退役锂电智能分选技术:助力新能源汽车产业可持续发展
  • Spring学习笔记【8】
  • 【嘉立创EDA】PCB 如何按板框轮廓进行铺铜
  • JVM调优实战 Day 6:JVM性能监控工具实战
  • Redis大规模Key遍历实战:性能与安全的最佳实践
  • 前端中的 CI/CD 教程详解(附实践方案)
  • 初学python的我开始Leetcode题10-3
  • Node.js-fs模块
  • 【Linux】Shell 脚本编程——条件测试与比较
  • python的易家宜超市云购物系统
  • 无人机灯光驱动模块技术解析
  • 京东正式开源 Taro on HarmonyOS C-API 版本,为鸿蒙应用跨端开发提供高性能框架
  • Xcode缓存清除
  • 【CUDA调优指南】缓存访存流程
  • Jenkins CLI 使用方法介绍
  • Jenkins JNLP与SSH节点连接方式对比及连接断开问题解决方案
  • 力扣2040两个有序数组的第K小乘积
  • Docker、Docker composer与Docker desktop
  • 英文摘要给成中文摘要模型
  • 探索解析C++ STL中的 list:双向链表的高效实现与迭代器
  • NCCN Guidelines Navigator:数智化工具引领肿瘤精准治疗新纪元
  • 八股文——JAVA基础:说一下C++与java的区别
  • 企业内部安全组网技术解析:安全通道选型、零信任架构与数据合规加密防护
  • 【AI论文】拖拽式大型语言模型:零样本提示到权重的生成
  • 打造灵活强大的PDF解析管道:从文本提取到智能分块的全流程实战
  • 从零构建 gRPC 跨语言通信:C++ 服务端与 C# 客户端完整指南
  • 数据库1.0
  • OceanBase向量检索在货拉拉的探索和实践