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

JVM 垃圾回收器

以下是对主流 JVM 垃圾回收器的详细解析,涵盖 

一、Serial GC(单线程串行回收器)

二、Parallel GC(吞吐量优先回收器)

三、CMS(Concurrent Mark Sweep,低延迟回收器)

四、G1(Garbage-First,区域分代回收器)

五、ZGC(超低延迟回收器)

六、Shenandoah(OpenJDK 低延迟回收器)

 的核心机制、适用场景及横向对比,帮助理解不同垃圾回收器的设计哲学与性能特点。

一、Serial GC(单线程串行回收器)

核心机制
  • 算法
    • 新生代:复制算法(Copying Algorithm),将存活对象从 Eden/Survivor 复制到另一块 Survivor。
    • 老年代:标记 - 整理算法(Mark-Compact),标记存活对象后压缩内存空间。
  • 执行特点
    • 单线程:GC 时需 Stop The World(STW),暂停所有应用线程,全程由一条 GC 线程完成。
    • 简单高效:无线程切换开销,适合内存较小的环境。
关键参数
-XX:+UseSerialGC        # 启用 Serial GC(默认用于 Client 模式)
-XX:SurvivorRatio=8     # Eden:Survivor 比例(默认 8:1)
适用场景
  • 嵌入式设备或 单核心服务器(如小型桌面应用)。
  • 内存 < 1GB 的场景,STW 时间可控。
优缺点
优点缺点
简单可靠,无额外内存开销单线程导致 STW 时间较长
适合内存小的场景无法利用多核 CPU 优势

二、Parallel GC(吞吐量优先回收器)

核心机制
  • 算法
    • 新生代:多线程复制算法,并行执行垃圾回收。
    • 老年代:多线程标记 - 整理算法(JDK 8 前为 Serial Old,JDK 9+ 为 Parallel Old)。
  • 执行特点
    • 多线程并行:通过 -XX:ParallelGCThreads 设置线程数,利用多核 CPU 缩短 STW 时间。
    • 目标吞吐量:通过 -XX:GCTimeRatio 控制 GC 时间占比(默认 99%,即 GC 时间 ≤ 1%)。
关键参数
-XX:+UseParallelGC      # 启用 Parallel GC(默认用于 Server 模式)
-XX:MaxGCPauseMillis=100 # 目标最大停顿时间(毫秒,动态调整堆大小)
-XX:GCTimeRatio=99      # 吞吐量目标(1/(1+N),N=99 即吞吐量 99%)
适用场景
  • 后台计算任务(如大数据处理、科学计算),优先保证吞吐量。
  • 堆内存中等大小(如 4-8GB),允许较短 STW 但需高持续处理能力。
优缺点
优点缺点
多线程提升吞吐量停顿时间仍随堆增大而增长
自动调优(自适应策略)无法满足低延迟需求

三、CMS(Concurrent Mark Sweep,低延迟回收器)

核心机制
  • 算法
    • 标记 - 清除(Mark-Sweep):老年代使用该算法,避免整理内存的 STW 开销。
    • 分代设计:新生代用 Parallel Scavenge(多线程复制),老年代用 CMS 并发回收。
  • 执行阶段(老年代):
    1. 初始标记(STW):标记根对象,耗时短。
    2. 并发标记:与应用线程并行标记可达对象。
    3. 重新标记(STW):修正并发标记期间的变动,耗时短。
    4. 并发清除:与应用线程并行清除垃圾对象。
关键参数
-XX:+UseConcMarkSweepGC  # 启用 CMS GC
-XX:CMSInitiatingOccupancyFraction=70 # 老年代占用 70% 时触发 GC
-XX:+CMSParallelRemarkEnabled # 启用并行重新标记(减少 STW 时间)
适用场景
  • 交互式应用(如 Web 服务器、前端服务),需降低 STW 对用户体验的影响。
  • 堆内存较大(如 8-16GB),但对象存活率较高(老年代占比大)。
优缺点
优点缺点
老年代并发回收,STW 时间短标记 - 清除导致内存碎片
适合低延迟场景并发阶段占用 CPU 资源
分代设计提升回收效率可能触发 "Concurrent Mode Failure"(回收速度慢于分配速度)

四、G1(Garbage-First,区域分代回收器)

核心机制
  • 分区(Region)设计
    • 将堆划分为大小相等的 Region(如 2MB-32MB),每个 Region 可动态扮演 Eden、Survivor、Old 或 Humongous(大对象)。
    • 优先回收价值高的区域:通过记录每个 Region 的垃圾占比,优先处理回收收益最大的区域(Garbage-First 得名)。
  • 算法
    • 新生代:多线程复制算法,回收 Eden/Survivor 区域。
    • 老年代:并发标记 + 混合回收(部分 Old Region + 新生代),基于标记 - 整理算法。
执行阶段
  1. 初始标记(STW):标记根对象。
  2. 并发标记:与应用线程并行标记可达对象。
  3. 最终标记(STW):处理 SATB 日志(Snapshot At The Beginning,记录并发阶段新增引用)。
  4. 筛选回收(STW):计算各 Region 回收收益,选择部分 Old Region 与新生代混合回收。
关键参数
-XX:+UseG1GC            # 启用 G1 GC
-XX:G1HeapRegionSize=4m # 设置 Region 大小(自动推算默认值)
-XX:MaxGCPauseMillis=200 # 目标最大停顿时间(默认 200ms)
-XX:G1MixedGCCountTarget=8 # 混合回收时最大 Region 数
适用场景
  • 大内存(8GB+) 且 需要兼顾吞吐量与低延迟 的场景(如微服务、中间件)。
  • 对象分配频率高(如新生代大对象多),或存在大量中等大小对象(避免进入 Humongous Region)。
优缺点
优点缺点
分区设计避免内存碎片内存占用高(每个 Region 需元数据)
可预测的停顿时间并发标记阶段耗 CPU 资源
混合回收应对老年代回收调优复杂度高于 CMS/Parallel

五、ZGC(超低延迟回收器)

核心机制
  • 着色指针(Colored Pointers)
    • 将对象引用的低 4 位用于存储 GC 状态(如标记位、重映射状态),无需修改对象头,减少内存访问开销。
  • 读屏障(Load Barrier)
    • 在读取对象引用时动态修正指针(如对象被移动到新 Region,通过读屏障获取新地址)。
  • 并发标记 - 整理
    • 全程几乎无 STW(仅初始标记和再标记有极短停顿,通常 <1ms),支持 TB 级堆内存。
执行阶段
  1. 初始标记(STW):标记根对象,耗时极短。
  2. 并发标记:与应用线程并行标记可达对象。
  3. 再标记(STW):处理并发标记期间的引用变动,耗时极短。
  4. 并发转移:移动存活对象到新 Region,通过读屏障修正所有引用。
关键参数
-XX:+UseZGC              # 启用 ZGC(JDK 11+)
-XX:ZHeapMaxSize=8t      # 最大堆内存(支持 TB 级)
-XX:ZCollectionInterval=1000 # 强制 GC 间隔(毫秒,避免碎片累积)
适用场景
  • 超大堆内存(16GB-8TB)且 对延迟敏感 的场景(如金融交易、实时数据处理)。
  • 云原生环境(如 Kubernetes 弹性扩缩容),需快速启动和低停顿。
优缺点
优点缺点
停顿时间 <10ms,几乎无感知吞吐量略低于 G1(约 95%)
支持动态堆大小调整仅 JDK 11+ 可用,需谨慎适配
分代设计(JDK 15+)提升年轻代回收效率

六、Shenandoah(OpenJDK 低延迟回收器)

核心机制
  • 转发指针(Forwarding Pointer)
    • 在对象头中添加指针,指向对象的新地址(移动后通过该指针修正引用)。
  • 布鲁姆过滤器(Bloom Filter)
    • 快速判断对象是否已被移动,减少无效的指针扫描,提升并发性能。
  • 并发标记 - 复制
    • 与 ZGC 类似,全程并发执行,仅初始标记和最终标记有短暂 STW。
执行阶段
  1. 初始标记(STW):标记根对象。
  2. 并发标记:与应用线程并行标记可达对象。
  3. 最终标记(STW):处理漏标的对象,耗时短。
  4. 并发回收:移动存活对象到新 Region,通过转发指针更新引用。
关键参数
-XX:+UseShenandoahGC     # 启用 Shenandoah(OpenJDK 12+)
-XX:ShenandoahGCMode=主动/被动 # 触发模式(主动模式基于内存阈值,被动响应分配压力)
-XX:MaxGCPauseMillis=10  # 目标停顿时间(默认 10ms)
适用场景
  • 大内存(8GB-2TB)且 需要 OpenJDK 原生支持 的场景(如开源项目、非商业环境)。
  • 对吞吐量要求中等,但需严格控制延迟的应用(如消息中间件、实时分析系统)。
优缺点
优点缺点
停顿时间与 ZGC 相当吞吐量低于 G1(约 90%)
内存占用低(转发指针仅占对象头)商业 JDK 需授权(OpenJDK 免费)
社区活跃,适配性强调优参数较多,需深入理解机制

七、横向对比表格

维度Serial GCParallel GCCMSG1ZGCShenandoah
设计目标简单单线程高吞吐量低延迟(老年代)平衡吞吐量与延迟超低延迟(TB 级)超低延迟(OpenJDK)
堆大小推荐小(<1GB)中等(4-8GB)中大(8-16GB)大(8GB+)超大(16GB+)大(8GB-2TB)
STW 时间中等短(老年代并发)可控(<500ms)极短(<10ms)极短(<10ms)
算法核心复制 + 标记整理并行复制 + 整理并发标记 - 清除分区 + 混合回收着色指针 + 并发整理转发指针 + 并发复制
适用场景嵌入式 / 单核心后台计算Web 服务微服务 / 中间件金融 / 实时数据开源 / OpenJDK 环境
JDK 版本全版本全版本JDK 1.4+JDK 7+JDK 11+OpenJDK 12+
典型参数-XX:+UseSerialGC-XX:+UseParallelGC-XX:+UseConcMarkSweepGC-XX:+UseG1GC-XX:+UseZGC-XX:+UseShenandoahGC

八、选择建议

  1. 小内存 / 简单场景
    • 优先选 Serial GC(单核心)或 Parallel GC(多核、需吞吐量)。
  2. 中等内存 / 低延迟需求
    • 选 CMS(老年代对象多)或 G1(对象分配频繁、需分代回收)。
  3. 大内存 / 超低延迟
    • 商业场景选 ZGC(JDK 11+,Oracle/OpenJDK);
    • 开源场景选 Shenandoah(OpenJDK 12+,避免授权问题)。
  4. 云原生 / 弹性扩缩容
    • 优先 ZGC(支持动态堆调整和超大内存)。

九、发展趋势

  • ZGC/Shenandoah 主导未来:逐步替代 G1 成为大内存场景的默认选择。
  • 分代与并发结合:如 ZGC 支持分代(JDK 15+),提升年轻代回收效率。
  • 硬件协同优化:利用 CPU 特性(如 AMD 的 MMU 分页)加速 GC 指针操作。

通过理解不同垃圾回收器的设计 trade-off,可根据具体业务需求(吞吐量、延迟、内存大小)选择最优方案,或通过组合参数(如 G1 的 -XX:InitiatingHeapOccupancyPercent)进一步调优。

相关文章:

  • 魔族密码--dp+map+substr
  • uniapp vue 开发微信小程序 分包梳理经验总结
  • 2024CCPC吉林省赛长春邀请赛 Java 做题记录
  • MAC常用操作整理
  • codeup添加流水线docker自动化部署
  • RSP-BSP-1
  • 使用 nvm 管理 Node.js 和 npm 版本
  • 《Effective Python》第三章 循环和迭代器——在遍历参数时保持防御性
  • 前端(vue)学习笔记(CLASS 6):路由进阶
  • Redis有哪些常用应用场景?
  • MySQL企业版免费开启,强先体验
  • 【Vue篇】潮汐中的生命周期观测站​
  • 深入掌握MyBatis:连接池、动态SQL、多表查询与缓存
  • ubuntu下配置vscode生成c_cpp_properties.json
  • Unity 如何使用Timeline预览、播放特效
  • 【NLP】36. 从指令微调到人类偏好:构建更有用的大语言模型
  • AI大模型从0到1记录学习numpy pandas day25
  • 两数之和 - 简单
  • 面试题之进程 PID 分配与回收算法:从理论到 Linux 内核实现
  • 【NLP】35. 构建高质量标注数据
  • 电子凭证会计数据标准推广至全国
  • 雷军:小米芯片采用3纳米制程,首款SUV“YU7”即将发布
  • 三人在共享单车上印小广告被拘,北京警方专项打击非法小广告
  • 首次公布!我国空间站内发现微生物新物种
  • 受贿1.29亿余元,黑龙江省原副省长王一新被判无期
  • 张国清将赴俄罗斯举行中俄“长江—伏尔加河”地方合作理事会第五次会议和“东北—远东”政府间合作委员会双方主席会晤