引言
在 JDK 21 中,Java 虚拟机 (JVM) 提供了多种垃圾收集器 (GC) 选项,其中 G1 (Garbage-First) 和 ZGC (Z Garbage Collector) 是两种备受关注的低延迟垃圾收集器。本文将深入对比这两种垃圾收集器,从原理、性能特性、适用场景、配置参数以及实际应用等方面进行详细分析,帮助开发者根据应用需求选择合适的垃圾收集器。
G1 垃圾收集器概述
基本原理
G1 是 Oracle JDK 中的一种分代垃圾收集器,自 JDK 7u4 引入,JDK 9 起成为默认 GC。它将堆内存划分为多个大小相等的 Region (区域),每个 Region 可以是 Eden、Survivor、Old 或 Humongous 类型。G1 使用 Remembered Set 避免全堆扫描,并通过 Pause Prediction Model 预测停顿时间。
主要特性
- 可预测的停顿时间: 目标停顿时间通常在 200ms 以内
- 高吞吐量: 在保持低延迟的同时提供良好的吞吐量
- 分代收集: 区分年轻代和老年代,优化不同生命周期对象的收集
- 并发标记: 部分收集过程与应用线程并发执行
JDK 21 中的改进
JDK 21 引入了 Generational G1 (代际 G1),通过 -XX:+UseGenerationalG1 启用,进一步优化代际内存布局和收集效率。
ZGC 垃圾收集器概述
基本原理
ZGC 是 Oracle JDK 11 引入的一种可扩展、低延迟的垃圾收集器,专为大堆内存设计。它使用 Colored Pointers (着色指针) 技术,将对象引用分为三类:强引用、弱引用和最终引用。ZGC 采用并发收集策略,将垃圾收集工作分散到多个阶段,大大减少停顿时间。
主要特性
- 极低延迟: 停顿时间通常小于 10ms
- 可扩展性: 支持 TB 级堆内存
- 并发收集: 几乎所有收集工作都与应用线程并发执行
- NUMA 友好: 优化多处理器系统上的内存访问
JDK 21 中的改进
JDK 21 对 ZGC 进行了多项优化,包括更好的并发处理、更高效的内存分配以及改进的 NUMA 支持。
性能对比
停顿时间
- G1: 提供可预测的停顿时间,默认目标 200ms,可通过参数调整到更低。但在高负载下可能出现较长的停顿。
- ZGC: 停顿时间极短,通常在 1-10ms 范围内,几乎不受堆大小影响。
吞吐量
- G1: 吞吐量较高,在大多数场景下可达到 90% 以上。
- ZGC: 吞吐量稍低,通常在 80-95% 之间,但随着 JDK 版本改进而提升。
CPU 使用率
- G1: CPU 使用率适中,年轻代收集较为高效。
- ZGC: CPU 使用率较高,因为并发收集需要更多计算资源。
内存开销
- G1: Remembered Set 和其他数据结构会带来额外内存开销,通常在 5-10%。
- ZGC: 使用 Colored Pointers,需要额外的内存位来存储对象状态,开销相对较低。

