G1、ZGC、Shenandoah

现代垃圾回收器

🎯 面试重点

📖 G1 收集器

G1 特点

/**
 * G1 (Garbage First) 收集器
 * 
 * 特点:
 * 1. 区域(Region)概念
 * 2. 复制 + 标记-整理
 * 3. 可预测停顿时间
 * 4. 优先回收垃圾最多的区域
 * 5. JDK 9+ 默认收集器
 */
public class G1Features {
    // 启动参数
    /*
     * -XX:+UseG1GC                    // 启用 G1
     * -XX:MaxGCPauseMillis=200        // 最大停顿时间目标
     * -XX:G1HeapRegionSize=n          // Region 大小(1MB-32MB)
     * -XX:InitiatingHeapOccupancyPercent=45  // 触发 Mixed GC 阈值
     */
}

G1 区域

/**
 * G1 区域概念
 * 
 * G1 将堆划分为多个大小相等的 Region(区域)
 * 每个 Region 可以是 Eden、Survivor、Old、HUMOUS(大对象)
 * 
 * ┌─────────────────────────────────────────────────┐
 * │                   堆内存                          │
 * │  ┌──────┬──────┬──────┬──────┬──────┬──────┐   │
 * │  │ E    │ E    │ S    │ O    │ O    │ H    │   │
 * │  ├──────┴──────┴──────┴──────┴──────┴──────┤   │
 * │  │ E    │ E    │ O    │ O    │ H    │ E    │   │
 * │  ├──────┴──────┴──────┴──────┴──────┴──────┤   │
 * │  │ S    │ O    │ O    │ E    │ E    │ S    │   │
 * └──────────────────────────────────────────────┘   │
 * 
 * Region 大小:1MB - 32MB(通过 -XX:G1HeapRegionSize 设置)
 * 大对象(HUMOUS):超过 Region 一半的对象
 */
public class G1Regions {}

G1 回收流程

/**
 * G1 回收流程:
 * 
 * 1. Young GC(年轻代收集)
 *    - 收集所有年轻代 Region
 *    - 复制到 Survivor Region
 *    - STW(Stop The World)
 * 
 * 2. Mixed GC(混合收集)
 *    - 收集所有年轻代 + 部分老年代
 *    - 多次 Young GC 后触发
 *    - STW
 * 
 * 3. Full GC(完整收集)
 *    - 串行/并行 Full GC
 *    - 发生条件:内存不足时
 */
public class G1CollectionProcess {
    // Young GC 流程
    /*
     * 1. 根扫描
     * 2. 更新 RSet
     * 3. 复制存活对象到 Survivor
     * 4. 处理引用
     */
    
    // 触发 Mixed GC 条件
    /*
     * G1MixedGCLiveThresholdPercent (默认 85%)
     * G1HeapWastePercent (默认 5%)
     * G1ReservePercent (默认 10%)
     */
}

RSet 和 Card Table

/**
 * RSet(Remembered Set)
 * 
 * 作用:记录其他 Region 对本 Region 的引用
 * 目的:避免全堆扫描,快速找到存活对象
 * 
 * 每个 Region 有一个 RSet
 * RSet 使用 Card Table 实现
 */
public class RSetExample {
    // Card Table
    /*
     * 每个 Card 512字节
     * 如果一个对象引用了其他 Region 的对象,对应 Card 标记为 dirty
     * 
     *     Region 1                    Region 2
     *  ┌────────────┐            ┌────────────┐
     *  │ Card Table  │     引用   │            │
     *  │ [ ][ ][DIRTY]│ ────────→│            │
     *  └────────────┘            └────────────┘
     */
}

📖 ZGC 收集器

ZGC 特点

/**
 * ZGC (Z Garbage Collector)
 * 
 * 特点:
 * 1. 并发收集(几乎全部并发)
 * 2. 染色指针(Colored Pointers)
 * 3. 读屏障(Load Barrier)
 * 4. 不分代(或者说动态分代)
 * 5. 停顿时间不超过 10ms
 * 6. 支持 TB 级堆内存
 */
public class ZGCFeatures {
    // 启动参数
    /*
     * -XX:+UseZGC                    // 启用 ZGC
     * -XX:ConcGCThreads=auto        // 并发 GC 线程数
     * -XX:ParallelGCThreads=auto    // 并行 GC 线程数
     * -XX:ZHeapSize=n               // 堆大小
     */
}

染色指针

/**
 * 染色指针(Colored Pointers)
 * 
 * 原理:在对象的 64 位指针上使用几位作为标记位
 * 
 * 标记位含义(64位):
 * 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000 0 0 0 0
 *                                                                          ↑ 颜色位
 * 
 * 颜色:
 * 0:正常对象
 * 1:重映射(Relocated)
 * 2:待回收(Marked0)
 * 4:已标记(Marked1)
 * 8:已初始化(Finalizable)
 */
public class ColoredPointers {
    // 优点
    /*
     * 1. 不需要额外的元数据空间
     * 2. 可以在运行时知道对象状态
     * 3. 不需要Barrier修改对象头
     * 
     * 限制:43 位寻址空间(8TB)
     */
}

ZGC 回收流程

/**
 * ZGC 回收阶段:
 * 
 * 1. 停顿标记(STW)
 *    - 标记 GC Roots
 *    - 停顿时间 < 1ms
 * 
 * 2. 并发标记
 *    - 遍历对象图
 *    - 标记所有存活对象
 *    - 不停顿
 * 
 * 3. 重新标记(STW)
 *    - 处理并发期间的变化
 *    - 停顿时间 < 1ms
 * 
 * 4. 并发重分配
 *    - 复制存活对象到新 Region
 *    - 更新指针
 *    - 不停顿
 * 
 * 5. 并发引用处理
 *    - 更新引用
 *    - 不停顿
 */
public class ZGCPhases {}

📖 Shenandoah 收集器

Shenandoah 特点

/**
 * Shenandoah 收集器
 * 
 * 特点:
 * 1. 并发回收(与应用并发)
 * 2. 转发指针(Brooks Pointer)
 * 3. 不分代(实验性分代)
 * 4. 与 G1 类似,使用 Region
 * 5. 停顿时间可控
 * 
 * 与 ZGC 对比:
 * - ZGC:染色指针,需要特定 JDK 版本
 * - Shenandoah:转发指针,OpenJDK 特有
 */
public class ShenandoahFeatures {
    // 启动参数
    /*
     * -XX:+UseShenandoahGC
     * -XX:ShenandoahGCHeuristics=adaptive
     * 
     * Heuristics:
     * - adaptive:自适应
     * - static:静态
     * - compact:压缩优先
     * - aggressive:激进
     */
}

转发指针

/**
 * 转发指针(Brooks Pointer)
 * 
 * 在对象头部添加一个指针
 * 正常对象:指针指向自己
 * 移动后:指针指向新位置
 * 
 * 读写时检查指针:
 * - 读取:通过指针找到最新对象
 * - 写入:更新指针
 */
public class BrooksPointer {
    // 读屏障
    /*
     * Object getObjectField(Field f) {
     *     Object o = f.get(this);
     *     // 读屏障检查
     *     if (o == FORWARDING_PTR) {
     *         o = o.getForwardee();
     *     }
     *     return o;
     * }
     */
}

📖 对比总结

/**
 * 现代 GC 对比
 */
public class GCComparison {
    /*
     * | 特性        | G1           | ZGC           | Shenandoah    |
     * |-------------|--------------|---------------|---------------|
     * | 分代        | 分代         | 不分代        | 不分代(实验)|
     * | 内存结构    | Region       | Region        | Region        |
     * | 并发程度    | 部分并发     | 全部并发       | 全部并发      |
     * | 停顿时间    | 可控         | <10ms         | <10ms         |
     * | 最大堆      | -            | 8TB           | -             |
     * | 原理        | RSet         | 染色指针      | 转发指针      |
     * | JDK 版本    | 9+ 默认      | 11+           | 8+            |
     * | 生产可用    | 是           | 是(11+)       | 是            |
     */
}

📖 面试真题

Q1: G1 和 CMS 的区别?

答:

Q2: ZGC 为什么快?

答:

Q3: G1 的 Region 大小如何设置?

答:


⭐ 重点:现代回收器是 JDK 升级的重点,G1 必须掌握,ZGC 是未来趋势