一、G1 收集器核心知识点
1. 基本特性与设计目标
- 定位:面向服务器端,适用于多处理器、大容量内存(推荐 8GB 以上)场景
- 核心目标:在满足低停顿时间要求的同时,保持高吞吐量
- 关键优势 :
- 并行与并发:利用多核 CPU 缩短 STW 时间,部分阶段与用户线程并发
- 分代收集:保留年轻代 / 老年代概念,但非物理隔离(基于 Region 集合)
- 空间整合:整体标记 - 整理,局部复制算法,无内存碎片
- 可预测停顿:支持通过参数指定最大停顿时间
2. 内存布局

- Region 大小 :默认堆大小 / 2048(1MB~32MB,2 的 N 次幂),可通过
-XX:G1HeapRegionSize指定 - 年轻代配置 :
- 初始占比 5%(
-XX:G1NewSizePercent) - 最大占比 60%(
-XX:G1MaxNewSizePercent) - Eden:Survivor 默认 8:1:1
- 初始占比 5%(
- 大对象处理 :
- 超过 Region 大小 50% 的对象存入 Humongous 区
- 超大对象可横跨多个 Region
- Full GC 时一同回收
3. 垃圾收集流程

- 初始标记(STW):快速记录 GC Roots 直接引用,速度快
- 并发标记:与用户线程并行,遍历对象图
- 最终标记(STW):修正并发标记期间的对象状态变化
- 筛选回收(STW) :
- 对 Region 按回收价值排序
- 根据
-XX:MaxGCPauseMillis(默认 200ms)制定回收计划 - 选择回收价值最大的 Region(Garbage-First 命名由来)
4. 收集类型
| 收集类型 | 触发条件 | 回收范围 | 特点 |
|---|---|---|---|
| Young GC | Eden 区满且回收时间接近 MaxGCPauseMillis | 年轻代 Region | 复制算法,STW |
| Mixed GC | 老年代占比达 IHOP 阈值(默认 45%) | 年轻代 + 部分老年代 + Humongous 区 | 优先回收价值高的老年代 Region |
| Full GC | Mixed GC 时无足够空 Region 承载存活对象 | 全堆(含 Humongous 区) | 单线程标记 - 清理 - 压缩,耗时久 |
5. 核心参数配置
| 参数 | 作用 | 默认值 |
|---|---|---|
-XX:+UseG1GC |
启用 G1 收集器 | - |
-XX:MaxGCPauseMillis |
目标停顿时间 | 200ms |
-XX:ParallelGCThreads |
GC 工作线程数 | CPU 核心数 |
-XX:InitiatingHeapOccupancyPercent |
Mixed GC 触发阈值 | 45% |
-XX:G1MixedGCLiveThresholdPercent |
Region 回收存活阈值 | 85% |
-XX:MaxTenuringThreshold |
对象晋升老年代最大年龄 | 15 |
6. 优化建议与适用场景
- 优化核心 :
- 合理设置
MaxGCPauseMillis(建议 100-300ms),避免过短导致频繁 GC - 控制年轻代 GC 后存活对象数量,防止提前进入老年代
- 合理设置
- 适用场景 :
- 堆内存 8GB 以上
- 50% 以上堆被存活对象占用
- 垃圾回收时间超过 1 秒
- 要求停顿时间 500ms 以内
- 高并发场景(如 Kafka 等消息中间件)
二、ZGC 收集器核心知识点
1. 基本特性与设计目标
- 定位:JDK11 + 实验性低延迟收集器(JDK14 正式支持 Windows)
- 核心目标 :
- 支持 TB 级堆内存(最大 16TB,JDK13+)
- 最大 GC 停顿时间≤10ms
- 吞吐量降低不超过 15%
- 停顿时间不随堆大小增长而增加
- 关键技术:颜色指针、读屏障、NUMA 感知
2. 内存布局

- 无分代设计:暂时不支持分代,后续版本计划优化
- NUMA 优化:自动感知服务器 NUMA 架构,优先使用本地内存
3. 核心技术原理
(1)颜色指针

- 优势 :
- Region 可立即释放,无需等待所有引用修正
- 仅需读屏障,减少内存屏障开销
- 扩展性强,可记录更多 GC 相关信息
- 标记机制 :
- 每次 GC 周期交替使用 Marked0/Marked1
- 通过颜色位判断对象标记状态
(2)读屏障
-
作用:在读取对象引用时触发,修正被移动对象的指针
-
实现逻辑 :
Object o = obj.fieldA; // 读取对象引用 <读屏障> // 检查指针颜色 if (指针为Bad Color) { 修正指针到新地址(自愈能力) } -
性能开销:约 4% 的执行开销
4. 垃圾收集流程

- 关键特性 :
- 指针自愈:用户线程访问旧对象时自动修正指针
- 重分配集:选择需回收的 Region 集合
- 并发重映射:与下次标记阶段合并,减少遍历开销
5. 触发机制与参数配置
-
触发机制 :
- 定时触发(默认禁用,
ZCollectionInterval配置) - 预热触发(堆达 10%、20%、30% 时,最多 3 次)
- 分配速率触发(基于正态分布预测内存耗尽时间)
- 主动触发(堆增长 10% 或超 5 分钟,且间隔超 49 倍 GC 时长)
- 定时触发(默认禁用,
-
核心参数 :
plaintext
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC // 启用ZGC -XX:ZHeapLimit=16T // 最大堆限制(JDK13+) -XX:ZCollectionInterval=300 // 定时触发间隔(秒)
6. 存在问题与解决方案
- 主要问题 :
- 浮动垃圾:GC 周期长(可能达分钟级),期间产生的新垃圾需下次回收
- 无分代设计:"朝生夕死" 对象无法及时回收
- 解决方案 :
- 临时方案:增大堆容量,延长程序喘息时间
- 根本方案:未来版本引入分代收集
三、垃圾收集器选择指南

- JDK 默认收集器 :
- JDK1.8:Parallel(年轻代 + 老年代)
- JDK1.9+:G1 收集器
四、基础概念(面试高频)
1. 安全点(Safe Point)
- 定义:线程状态确定的代码位置,GC 需等待所有线程到达安全点才能执行
- 常见位置:方法返回前、方法调用后、异常抛出点、循环末尾
- 实现机制:通过标志位轮询,线程主动在安全点挂起
2. 安全区域(Safe Region)
- 适用场景:线程处于 Sleep / 中断状态,无法响应 GC 中断请求
- 定义:一段引用关系不变的代码片段,任意位置开始 GC 都安全
3. 关键算法对比
| 算法 | 收集器 | 优点 | 缺点 |
|---|---|---|---|
| 复制算法 | G1、ZGC(年轻代) | 无内存碎片,效率高 | 需额外空间 |
| 标记 - 清理 | CMS | 无需复制,开销小 | 产生内存碎片 |
| 标记 - 整理 | G1(整体)、ZGC | 无内存碎片 | 整理阶段开销大 |