目录
- 🧹 第一章:垃圾回收算法进化史
- 🚂 JDK7时代:Serial GC(老式吸尘器)
- 🚜 JDK8默认:Parallel GC(多线程清洁队)
- ✈️ JDK11+新宠:G1 GC(智能分拣机器人)
- 🚀 JDK12+实验品:Shenandoah(低延迟特工)
- ⚡ JDK15+新贵:ZGC(太空时代科技)
- 🧪 第二章:GC算法原理实验室
- 1. 标记-清除(Mark-Sweep)
- 2. 标记-整理(Mark-Compact)
- 3. 复制算法(Copying)
- 🛠️ 第三章:实战调优指南
- 1. 查看当前GC
- 2. 生成堆转储
- . 推荐JVM参数(JDK17+)
- 4. 常见问题处理
- 🌟 第四章:未来已来(JDK21新特性)
- 1. 分代式ZGC(里程碑!)
- 2. 虚拟线程友好GC
- 3. 向量化GC(实验室阶段)
- 💡 终极心法
🧹 第一章:垃圾回收算法进化史
🚂 JDK7时代:Serial GC(老式吸尘器)
- 算法:标记-清除(Mark-Sweep)
- 特点:
- 单线程STW(Stop-The-World)
- 简单粗暴,适合客户端应用
- 参数:-XX:+UseSerialGC
幽默时刻:
- 新生代:“我要GC了!”
- JVM:“全体线程暂停!等这位老爷爷慢慢打扫…”
- 应用线程:“卡成PPT了喂!”
🚜 JDK8默认:Parallel GC(多线程清洁队)
- 算法:标记-整理(Mark-Compact)
- 特点:
- 多线程并行GC
- 吞吐量优先
- 参数:-XX:+UseParallelGC
性能对比:
指标 | Serial GC | Parallel GC |
---|---|---|
GC时间 | 200ms | 80ms |
吞吐量 | 70% | 90%+ |
暂停时间 | 长 | 中等 |
✈️ JDK11+新宠:G1 GC(智能分拣机器人)
- 算法:分Region收集 + 标记-整理
- 黑科技:
- 预测停顿时间(-XX:MaxGCPauseMillis=200)
- 优先清理垃圾最多的Region
- 参数:-XX:+UseG1GC
G1的内心戏: “根据历史数据,这次GC我只扫3个最脏的Region,保证200ms内完事~”
🚀 JDK12+实验品:Shenandoah(低延迟特工)
- 绝活:并发压缩(不用STW!)
- 魔法原理:
- 读屏障(Read Barrier)技术
- 像变魔术时换掉观众手里的牌
- 参数:-XX:+UseShenandoahGC
⚡ JDK15+新贵:ZGC(太空时代科技)
- 目标:停顿时间<10ms(不管堆多大!)
- 秘技:
- 染色指针(Colored Pointers)
- 内存映射魔法
- 参数:-XX:+UseZGC
对比表:
GC算法 | JDK引入 | 最大优势 | 适用场景 |
---|---|---|---|
Serial | 1.0 | 简单稳定 | 客户端/嵌入式 |
Parallel | 1.2 | 高吞吐量 | 批处理系统 |
CMS | 1.4 | 低延迟 | 已淘汰(JDK14移除) |
G1 | 9 | 平衡吞吐/延迟 | 主流服务端默认 |
Shenandoah | 12 | 超低延迟 | 金融交易系统 |
ZGC | 15 | 超大堆无感 | 云原生/大数据 |
🧪 第二章:GC算法原理实验室
1. 标记-清除(Mark-Sweep)
内存布局:
[已用][已用][空闲][已用][垃圾][垃圾]
标记后:
[已用][已用][空闲][已用][X][X]
清除后:
[已用][已用][空闲][已用][空闲][空闲]
- 缺点:内存碎片化(像瑞士奶酪)
2. 标记-整理(Mark-Compact)
整理前:
[A][B][垃圾][C][垃圾][D]
整理后:
[A][B][C][D][空闲][空闲]
- 优点:解决碎片问题
- 代价:移动对象需要更多时间
3. 复制算法(Copying)
From区:
[A][B][垃圾][C]
To区:
[A][B][C]
- 年轻代标配:Eden + Survivor区就是这种设计
🛠️ 第三章:实战调优指南
1. 查看当前GC
jstat -gc <pid> 1000 # 每秒打印GC统计
2. 生成堆转储
jmap -dump:live,format=b,file=heap.hprof <pid>
. 推荐JVM参数(JDK17+)
-Xms4g -Xmx4g # 堆大小固定避免震荡
-XX:+UseZGC # 选用ZGC
-XX:MaxGCPauseMillis=10 # 目标暂停时间
-XX:SoftMaxHeapSize=3g # 弹性堆上限
4. 常见问题处理
频繁Full GC可能原因:
- 内存泄漏(用MAT分析)
- Survivor区过小(调整-XX:SurvivorRatio)
- 大对象直接进老年代(检查-XX:PretenureSizeThreshold)
🌟 第四章:未来已来(JDK21新特性)
1. 分代式ZGC(里程碑!)
- 年轻代/老年代分代收集
- 参数:-XX:+ZGenerational
2. 虚拟线程友好GC
- 协程局部变量自动回收
- 不再需要ThreadLocal清理
3. 向量化GC(实验室阶段)
- 利用SIMD指令加速标记
- 理论速度提升4-8倍
💡 终极心法
“没有最好的GC,只有最适合场景的GC”
- 追求吞吐量:Parallel GC
- 平衡型应用:G1 GC
- 低延迟要求:ZGC/Shenandoah
- 怀旧玩家:Serial GC(开玩笑的~)
下次GC发生时,不妨对它说:“辛苦啦,记得把我刚创建的那堆临时对象扫干净哦~” 😄
👉 动手时间:
- 用jvisualvm观察你的应用GC曲线
- 尝试更换GC算法并对比性能
- 用jmap分析堆内存中的"大胃王"对象