垃圾回收器深度对比与调优策略
垃圾回收器深度对比与调优策略
📌 学习目标
- 掌握G1/ZGC/CMS核心工作原理差异
- 学会根据业务场景选择回收器
- 掌握回收器关键参数调优方法
- 结合项目案例进行实战分析
🧠 知识图谱
🔧 本地实验准备
1. 实验代码(G1vsZGCDemo.java)
public class G1vsZGCDemo {
// 持续生成大对象+存活对象
private static List<byte[]> longLive = new ArrayList<>();
private static List<byte[]> tempList = new ArrayList<>();
public static void main(String[] args) throws InterruptedException {
// 每5秒创建持久对象
new Thread(() -> {
while (true) {
longLive.add(new byte[1024 * 1024]); // 1MB
try { Thread.sleep(5000); }
catch (InterruptedException e) {}
}
}).start();
// 高频创建临时对象
while (true) {
for (int i = 0; i < 100; i++) {
tempList.add(new byte[1024]); // 1KB
}
tempList.clear();
Thread.sleep(10);
}
}
}
2. 实验步骤
# 编译代码
javac G1vsZGCDemo.java
# 使用不同回收器运行(开两个终端)
# 终端1:G1回收器
java -Xmx200m -XX:+UseG1GC -Xlog:gc*:file=g1.log G1vsZGCDemo
# 终端2:ZGC回收器
java -Xmx200m -XX:+UseZGC -Xlog:gc*:file=zgc.log G1vsZGCDemo
📊 GC日志分析实战
G1日志特征分析
[0.356s][info][gc] GC(0) Pause Young (Normal) 25M->12M(200M) 5.678ms
[3.452s][info][gc] GC(1) Pause Mixed 145M->89M(200M) 12.345ms
关键指标:
Young (Normal)
:年轻代回收Mixed
:混合回收(含老年代)- 暂停时间:5-15ms级别
ZGC日志特征分析
[0.456s][info][gc] GC(0) Pause Mark Start 0.025ms
[0.567s][info][gc] GC(0) Concurrent Mark 48M->48M(200M) 25.678ms
[0.789s][info][gc] GC(0) Pause Relocate Start 0.043ms
[0.891s][info][gc] GC(0) Concurrent Relocate 48M->32M(200M) 12.345ms
关键指标:
Concurrent
:并发阶段(无停顿)- 最大暂停时间:<1ms
- 内存整理通过指针转发实现
🛠 调优参数对比表
维度 | G1 | ZGC |
---|---|---|
核心参数 | -XX:MaxGCPauseMillis=200 | -XX:SoftMaxHeapSize=256m |
线程控制 | -XX:ConcGCThreads=4 | -XX:ConcGCThreads=8 |
内存预留 | -XX:G1ReservePercent=10 | 无需配置 |
大页支持 | -XX:+UseLargePages | -XX:+UseLargePages (必须) |
适用JDK | 8+ | 15+(生产建议17+) |
💼 项目实战:电子签章系统GC调优
原始参数
java -Xmx4g -Xms4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 ...
问题现象
- 每天发生2-3次Full GC,最大暂停1.2秒
- 老年代内存碎片率持续高于30%
调优步骤
- 升级JDK:JDK11 → JDK17(启用ZGC)
- 参数调整:
- -XX:+UseG1GC + -XX:+UseZGC + -XX:SoftMaxHeapSize=3g # 允许自动伸缩 + -XX:+UseTransparentHugePages
- 效果验证:
Full GC次数:2次/天 → 0次 最大暂停时间:1.2s → 8ms
📝 知识点总结
1:CMS和G1的主要区别?
- 内存模型:CMS基于传统分代,G1采用分区(Region)
- 回收算法:CMS标记-清除(内存碎片),G1标记-整理
- 暂停控制:G1可通过MaxGCPauseMillis预测停顿
- 适用场景:CMS适用于中小堆,G1适合8G+大堆
2:ZGC如何实现亚毫秒级停顿?
技术要点:
- 染色指针(Colored Pointers)存储元数据
- 并发重映射(非STW内存整理)
- 内存多重映射(虚拟地址复用)
- 全并发的标记-转移算法
Java 中常见的垃圾收集器