GC算法:垃圾回收员的996日常(CMS到ZGC进化史)

188 阅读3分钟

1.2 GC算法:垃圾回收员的996日常(CMS到ZGC进化史)


📌 本章学习地图

graph TD
    A[GC算法] --> B(基础原理)
    A --> C(算法家族)
    A --> D(实战调优)
    B --> B1(可达性分析)
    B --> B2(STW原理)
    C --> C1(Serial/Parallel)
    C --> C2(CMS的三次哭泣)
    C --> C3(G1的Region革命)
    C --> C4(ZGC的染色指针魔法)
    D --> D1(参数调优公式)
    D --> D2(日志分析技巧)
    D --> D3(OOM急救指南)

一、剧情版GC进化史

1. 初代清洁工:Serial GC

  • 人设:老实巴交的单线程大叔
  • 工作方式:收拾垃圾时让全公司(JVM)午休(STW)
  • 经典语录:"虽然慢,但我的扫帚(标记-整理算法)扫得最干净!"
  • 适用场景:单身公寓(客户端小程序)

2. 奋斗逼团队:Parallel GC

  • 人设:内卷的八爪鱼清洁队
  • 绝活:多线程疯狂打扫(吞吐量优先)
  • 翻车现场:追求速度时把办公桌(堆内存)撞得乱七八糟
  • 名场面:-XX:ParallelGCThreads参数引发的CPU群殴事件

3. 焦虑症患者:CMS

  • 人设:追求"世界和平"的和平主义者
  • 工作流程
    1. 初始标记(快闪打卡)
    2. 并发标记(边工作边记录)
    3. 重新标记(核对考勤)
    4. 并发清除(摸鱼式打扫)
  • 崩溃三连
    • 内存碎片化(办公室满地纸屑)
    • 并发失败(突然的加班需求)
    • 晋升失败(老年代空间不足)

4. 时间管理大师:G1

  • 黑科技:把办公室划成隔间(Region)
  • 工作守则
    • 预测垃圾量(-XX:MaxGCPauseMillis)
    • 优先打扫最脏区域(Remembered Set)
  • 凡尔赛发言:"我能同时照顾前台(Young GC)和总裁办公室(Mixed GC)"

5. 未来战士:ZGC

  • 超能力
    • 染色指针(Colored Pointer)
    • 多重影分身(并发处理)
  • 名场面:10TB堆内存下STW<1ms
  • 凡尔赛语录:"停顿是什么?我字典里没有这个词"

二、硬核技术解析

CMS的三大致命伤

// 典型错误配置案例
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70 // 触发阈值
-XX:+UseCMSInitiatingOccupancyOnly     // 强制阈值生效
-XX:ParallelCMSThreads=4               // 并发线程数

调优公式
安全内存 = 老年代使用峰值 × (1 + 浮动垃圾比例)

G1的核心参数矩阵

参数作用域黄金值雷区警告
-XX:InitiatingHeapOccupancyPercent全局45%>50%易引发Full GC
-XX:G1ReservePercentSurvivor10%<5%导致晋升失败
-XX:G1HeapRegionSizeRegion根据堆大小调整必须是2的幂

ZGC的魔法原理

graph LR
    A[对象指针] --> B{颜色标记}
    B -->|0x0000| C[可回收]
    B -->|0x0001| D[已标记]
    B -->|0x0002| E[已重映射]
    style C fill:#f9c,stroke:#333
    style D fill:#6c9,stroke:#333
    style E fill:#69c,stroke:#333

三、面试暴击区

高频灵魂拷问

  1. "CMS的并发失败后会发生什么?"
    → 触发Serial Old GC(准备好解释晋升失败担保机制)

  2. "G1如何处理跨Region引用?"
    → Remembered Set + Post-Write Barrier(画图解释卡表结构)

  3. "ZGC如何实现并发压缩?"
    → 指针染色+多重映射(Linux的mmap黑魔法)

调优实战案例

场景:某电商大促期间频繁Full GC
线索

  • GC日志显示"Promotion Failed"
  • jstat显示老年代占用率>75%

解法

# 原配置
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70

# 修正方案
-XX:+UseG1GC 
-XX:MaxGCPauseMillis=200
-XX:G1ReservePercent=15

四、课后毒鸡汤

"学完GC算法就像拿到了扫帚,
但真正的高手,
是能让垃圾根本不产生的人(对象复用+代码优化)"

下节预告
《类加载机制:JVM的妈宝行为研究》
(双亲委派被嫌弃的一生)