垃圾回收器核心知识体系
目录
- 垃圾回收器组合关系
- 主流垃圾回收器详解
2.1 Serial/SerialOld
2.2 ParNew
2.3 CMS
2.4 Parallel Scavenge/Old
2.5 G1 - 综合对比与选型建议
- 附录:核心参数速查
一、垃圾回收器组合关系
基础概念
- 分代逻辑:除G1外,垃圾回收器需按年轻代+老年代组合使用
- 组合矩阵(经典JDK8版本):
二、主流垃圾回收器详解
2.1 Serial/SerialOld
核心特性
- 工作模式:单线程串行回收
- 代际归属:
- Serial:年轻代,使用复制算法
- SerialOld:老年代,使用标记-整理算法
- 适用场景:客户端程序/低配置设备(堆内存<100MB)
运行示意图
[用户线程] ----STW---> [Serial GC线程] ----STW---> [用户线程]
关键参数
-XX:+UseSerialGC # 显式启用组合
2.2 ParNew
核心特性
- 工作模式:多线程并行回收(Serial的多线程版本)
- 代际归属:年轻代,使用复制算法
- 搭配组合:CMS(JDK8前主流组合)
- 适用场景:Web服务类应用
性能特点
- 多CPU优势显著,单CPU反而不如Serial
- JDK9后被标记为Deprecated
关键参数
-XX:+UseParNewGC # 启用ParNew
-XX:ParallelGCThreads=4 # 指定线程数(默认为CPU核数)
2.3 CMS (Concurrent Mark Sweep)
核心特性
- 设计目标:最小化停顿时间(Low Latency)
- 代际归属:老年代,使用标记-清除算法
- 适用场景:响应敏感的B/S系统(订单、交易等)
四阶段工作流
- 初始标记(Initial Mark):STW,标记GC Roots直接关联对象
–> 耗时极短 - 并发标记(Concurrent Marking):与用户线程并发执行
–> 耗时长但无STW - 重新标记(Remark):STW,修正并发标记期间变化
–> 通过增量更新/原始快照(SATB)优化 - 并发清除(Concurrent Sweep):异步清理死亡对象
缺陷与处理策略
问题类型 | 现象 | 解决方案 |
---|---|---|
内存碎片 | Full GC频率增加 | 开启压缩:-XX:+UseCMSCompactAtFullCollection |
增量回收失败 | Concurrent Mode Failure | 后备方案:启用SerialOld |
浮动垃圾堆积 | 提早触发回收(JDK5默认68%) | 调整阈值:-XX:CMSInitiatingOccupancyFraction |
关键参数
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70 # 内存占用触发阈值
2.4 Parallel Scavenge/Parallel Old
核心特性
- 设计哲学:吞吐量优先(Throughput)
- 适用场景:后台计算型任务(数据分析、批量处理)
代际划分
回收器 | 代际 | 算法 |
---|---|---|
Parallel Scavenge | 年轻代 | 复制算法 |
Parallel Old | 老年代 | 标记-整理算法 |
自适应策略
关键参数
-XX:+UseParallelGC # Scavenge + Old组合
-XX:MaxGCPauseMillis=100 # 期望最大暂停时间(ms)
-XX:GCTimeRatio=99 # GC时间占比(公式:1/(1+N))
2.5 G1 (Garbage First)
核心突破
- Region划分:堆被划分为2048个等大Region(1MB~32MB)
- Mixed GC:统一管理年轻代/老年代,优先回收高收益Region
- 可预测暂停:通过
-XX:MaxGCPauseMillis
设置目标
内存模型
+---------------+ +---------------+ +---------------+
| Eden Region | | Survivor | | Old Region |
| (年轻代) | | Region | | (含Humongous) |
+---------------+ +---------------+ +---------------+
核心流程
-
年轻代GC(YGC):
- Evacuation阶段:存活对象拷贝到Survivor/Old
- 动态调整Eden/Survivor比例
-
混合回收(Mixed GC):
- 初始标记:YGC时捎带完成(Piggybacking)
- 并发标记:SATB算法处理快照
- 最终标记:处理剩余引用
- 筛选回收:根据停顿预测选择Region
关键优化
- Humongous Object:跨Region存储时直接进入老年代
- RSet(Remembered Set):解决跨Region引用扫描
- JDK12增强:支持自动返回未使用内存(
-XX:+G1PeriodicGCInvokesConcurrent
)
典型参数
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=16m
三、综合对比与选型建议
横评对比表
指标 | Serial | ParNew+CMS | Parallel | G1 |
---|---|---|---|---|
吞吐量 | 低(单线程) | 中等 | 高 | 高(大堆更优) |
暂停时间 | 长 | 短 | 中等 | 可预测 |
内存开销 | 低 | 高(RSet等) | 低 | 较高 |
JDK版本推荐 | <8(客户端) | 8(Web应用) | 8(计算密集型) | ≥9(默认) |
版本演进指南
-
JDK8及之前:
- 响应优先:ParNew + CMS(需监控Full GC)
- 吞吐优先:Parallel组合
- 超大堆试验:G1(>-Xmx16G)
-
JDK11+:
- 默认G1,4G~16G堆平衡选择
- 超低延迟需求:考虑ZGC(-XX:+UseZGC)
-
JDK17+:
- 生产级ZGC/Shenandoah
- G1持续优化Region弹性和NUMA感知
四、附录:核心参数速查
通用参数
-XX:+PrintGCDetails # 打印GC日志详情
-XX:+PrintGCDateStamps # 日志中添加时间戳
-Xloggc:/path/to/gc.log # 输出到独立文件
各回收器启用参数
回收器组合 | 参数 |
---|---|
Serial + SerialOld | -XX:+UseSerialGC |
ParNew + CMS | -XX:+UseParNewGC -XX:+UseConcMarkSweepGC |
Parallel组合 | -XX:+UseParallelGC |
G1 | -XX:+UseG1GC |