G1和ZGC垃圾收集器的主要区别是什么?
- 内容介绍
- 文章标签
- 相关问答
为什么你需要关注 GC 停顿时间?
响应时间是最关键的指标——停顿时间超过 1 秒往往代表着业务不可接受的卡顿。不过,此时选择一款能够提供可预测且极短停顿的垃圾收集器成为迫在眉睫的需求。
G1 与 ZGC 的基本原理
G1
- 面向服务器的大内存、多核机器设计。
-
将堆划分为多个大小相等的 RegionRegion 大小 = 堆大小 ÷ 2048,可通过
-XX:G1HeapRegionSize手动指定。 - Region 可以在运行时动态转换:新生代 → 老年代,甚至回收后 成为新生代。
- 大对象会被放入专门的 Humongous 区而不是直接进入老年代。
- 通过“并发标记 + 并发整理”实现高吞吐量,同时提供可配置的停顿目标。
ZGC
- 定位为“低延迟”垃圾收集器,目标停顿时间不超过 10 ms。
- 支持 TB 级别的大堆内存,单代。
- 关键技术包括颜色指针和读屏障实现几乎全程并发的标记‑整理算法。
- 采用基于 Region 的内存布局。但不进行代际区分,使得迁移成本更低。
两者之间的关键区别
并发重分配
G1:在每次回收前会对所有 Region 计算“回收价值/成本”。依据使用者设定的停顿目标,只挑选能够在限定时间内完成的 Region。例如当期望停顿 ≤200 ms。而老年代有 1000 个满载 Region 时G1 可能只回收价值最高的 800 个,以严格控制停顿。
并发标记方式
ZGC:标记信息直接写入对象指针的颜色位,而不是在对象本身添加标记位。怎么说呢,这样即使在标记阶段也能保持几乎零暂停。 仅在初始标记和最终标记阶段出现极短的 STW。G1:使用传统的对象头部标记。一样支持并发标记,但仍需在某些阶段暂停线程以更新对象状态。
颜色指针
ZGC 为每个对象指针预留若干位作为颜色位,用来记录对象是否已被标记、是否已转移等信息。不过,该机制大幅降低了读写屏障的开销。使得 GC 的整体延迟保持在毫秒级别。
Pausetime vs 吞吐量取舍
- ZGC:Pausetime 为首要目标。吞吐量略逊于 G1,但对超大堆和严格 latency 要求场景表现优异。话说回来,
- G1:Pausetime 可配置且通常在数十毫秒范围;在中等堆大小下拥有更高吞吐量。
适用场景对比
何时选择 G1?
- 程序整体吞吐可以稍微牺牲,只要 GC 不导致明显卡顿即可。
调优参数速查表
| G1 调优关键参数 | |
|---|---|
| -XX:+UseG1GC | 启用 G1 收集器 |
| -XX:MaxGCPauseMillis= | SLA 停顿目标,例如 100 |
| -XX:G1HeapRegionSize= | 手动指定 Region 大小 | -XX:G1NewSizePercent=<%> | 新生代初始占比 |
| -XX:G1MaxNewSizePercent=<%> | 新生代最大占比 |
| -XX:G1HeapWastePercent=<%> | 混合回收触发阈值 |
| ZGC 调优关键参数 | -XX:+UseZGC | 启用 ZGC 收集器 |
|---|---|
| -XX:ZCollectionInterval= | 强制两次 GC 间隔。适用于极端低延迟需求 |
| -XX:ZAllocationSpikeTolerance=<%> | 内存分配突增容忍阈值,可防止频繁触发 Full GC |
Pain Point 小结 & 行动建议
- 如果你的业务“响应时间必须 ≤ 1 秒”,且堆容量已突破 8 GB,请立即评估切换到 ZGC,并结合上述参数进行细化调优。
- 当堆容量在 4 GB–8 GB 区间、希望兼顾吞吐与可控停顿时首选 G1,并通过 “-XX:MaxGCPauseMillis” 精准设定 SLA。
- 对于小于 100 MB 的轻量级应用,无需使用上述复杂收集器——串行收集器更轻便、更易调试。按理说,
通过明确业务痛点、匹配对应 GC 特性。再结合实测数据微调参数,你就能把 “垃圾回收导致卡顿” 的隐患降到最低,让程序始终保持高速响应!
为什么你需要关注 GC 停顿时间?
响应时间是最关键的指标——停顿时间超过 1 秒往往代表着业务不可接受的卡顿。不过,此时选择一款能够提供可预测且极短停顿的垃圾收集器成为迫在眉睫的需求。
G1 与 ZGC 的基本原理
G1
- 面向服务器的大内存、多核机器设计。
-
将堆划分为多个大小相等的 RegionRegion 大小 = 堆大小 ÷ 2048,可通过
-XX:G1HeapRegionSize手动指定。 - Region 可以在运行时动态转换:新生代 → 老年代,甚至回收后 成为新生代。
- 大对象会被放入专门的 Humongous 区而不是直接进入老年代。
- 通过“并发标记 + 并发整理”实现高吞吐量,同时提供可配置的停顿目标。
ZGC
- 定位为“低延迟”垃圾收集器,目标停顿时间不超过 10 ms。
- 支持 TB 级别的大堆内存,单代。
- 关键技术包括颜色指针和读屏障实现几乎全程并发的标记‑整理算法。
- 采用基于 Region 的内存布局。但不进行代际区分,使得迁移成本更低。
两者之间的关键区别
并发重分配
G1:在每次回收前会对所有 Region 计算“回收价值/成本”。依据使用者设定的停顿目标,只挑选能够在限定时间内完成的 Region。例如当期望停顿 ≤200 ms。而老年代有 1000 个满载 Region 时G1 可能只回收价值最高的 800 个,以严格控制停顿。
并发标记方式
ZGC:标记信息直接写入对象指针的颜色位,而不是在对象本身添加标记位。怎么说呢,这样即使在标记阶段也能保持几乎零暂停。 仅在初始标记和最终标记阶段出现极短的 STW。G1:使用传统的对象头部标记。一样支持并发标记,但仍需在某些阶段暂停线程以更新对象状态。
颜色指针
ZGC 为每个对象指针预留若干位作为颜色位,用来记录对象是否已被标记、是否已转移等信息。不过,该机制大幅降低了读写屏障的开销。使得 GC 的整体延迟保持在毫秒级别。
Pausetime vs 吞吐量取舍
- ZGC:Pausetime 为首要目标。吞吐量略逊于 G1,但对超大堆和严格 latency 要求场景表现优异。话说回来,
- G1:Pausetime 可配置且通常在数十毫秒范围;在中等堆大小下拥有更高吞吐量。
适用场景对比
何时选择 G1?
- 程序整体吞吐可以稍微牺牲,只要 GC 不导致明显卡顿即可。
调优参数速查表
| G1 调优关键参数 | |
|---|---|
| -XX:+UseG1GC | 启用 G1 收集器 |
| -XX:MaxGCPauseMillis= | SLA 停顿目标,例如 100 |
| -XX:G1HeapRegionSize= | 手动指定 Region 大小 | -XX:G1NewSizePercent=<%> | 新生代初始占比 |
| -XX:G1MaxNewSizePercent=<%> | 新生代最大占比 |
| -XX:G1HeapWastePercent=<%> | 混合回收触发阈值 |
| ZGC 调优关键参数 | -XX:+UseZGC | 启用 ZGC 收集器 |
|---|---|
| -XX:ZCollectionInterval= | 强制两次 GC 间隔。适用于极端低延迟需求 |
| -XX:ZAllocationSpikeTolerance=<%> | 内存分配突增容忍阈值,可防止频繁触发 Full GC |
Pain Point 小结 & 行动建议
- 如果你的业务“响应时间必须 ≤ 1 秒”,且堆容量已突破 8 GB,请立即评估切换到 ZGC,并结合上述参数进行细化调优。
- 当堆容量在 4 GB–8 GB 区间、希望兼顾吞吐与可控停顿时首选 G1,并通过 “-XX:MaxGCPauseMillis” 精准设定 SLA。
- 对于小于 100 MB 的轻量级应用,无需使用上述复杂收集器——串行收集器更轻便、更易调试。按理说,
通过明确业务痛点、匹配对应 GC 特性。再结合实测数据微调参数,你就能把 “垃圾回收导致卡顿” 的隐患降到最低,让程序始终保持高速响应!

