JVM 垃圾收集器(G1&ZGC)

一、G1 收集器核心知识点

1. 基本特性与设计目标

  • 定位:面向服务器端,适用于多处理器、大容量内存(推荐 8GB 以上)场景
  • 核心目标:在满足低停顿时间要求的同时,保持高吞吐量
  • 关键优势
    • 并行与并发:利用多核 CPU 缩短 STW 时间,部分阶段与用户线程并发
    • 分代收集:保留年轻代 / 老年代概念,但非物理隔离(基于 Region 集合)
    • 空间整合:整体标记 - 整理,局部复制算法,无内存碎片
    • 可预测停顿:支持通过参数指定最大停顿时间

2. 内存布局

  • Region 大小 :默认堆大小 / 2048(1MB~32MB,2 的 N 次幂),可通过-XX:G1HeapRegionSize指定
  • 年轻代配置
    • 初始占比 5%(-XX:G1NewSizePercent
    • 最大占比 60%(-XX:G1MaxNewSizePercent
    • Eden:Survivor 默认 8:1:1
  • 大对象处理
    • 超过 Region 大小 50% 的对象存入 Humongous 区
    • 超大对象可横跨多个 Region
    • Full GC 时一同回收

3. 垃圾收集流程

  • 初始标记(STW):快速记录 GC Roots 直接引用,速度快
  • 并发标记:与用户线程并行,遍历对象图
  • 最终标记(STW):修正并发标记期间的对象状态变化
  • 筛选回收(STW)
    • 对 Region 按回收价值排序
    • 根据-XX:MaxGCPauseMillis(默认 200ms)制定回收计划
    • 选择回收价值最大的 Region(Garbage-First 命名由来)

4. 收集类型

收集类型 触发条件 回收范围 特点
Young GC Eden 区满且回收时间接近 MaxGCPauseMillis 年轻代 Region 复制算法,STW
Mixed GC 老年代占比达 IHOP 阈值(默认 45%) 年轻代 + 部分老年代 + Humongous 区 优先回收价值高的老年代 Region
Full GC Mixed GC 时无足够空 Region 承载存活对象 全堆(含 Humongous 区) 单线程标记 - 清理 - 压缩,耗时久

5. 核心参数配置

参数 作用 默认值
-XX:+UseG1GC 启用 G1 收集器 -
-XX:MaxGCPauseMillis 目标停顿时间 200ms
-XX:ParallelGCThreads GC 工作线程数 CPU 核心数
-XX:InitiatingHeapOccupancyPercent Mixed GC 触发阈值 45%
-XX:G1MixedGCLiveThresholdPercent Region 回收存活阈值 85%
-XX:MaxTenuringThreshold 对象晋升老年代最大年龄 15

6. 优化建议与适用场景

  • 优化核心
    • 合理设置MaxGCPauseMillis(建议 100-300ms),避免过短导致频繁 GC
    • 控制年轻代 GC 后存活对象数量,防止提前进入老年代
  • 适用场景
    • 堆内存 8GB 以上
    • 50% 以上堆被存活对象占用
    • 垃圾回收时间超过 1 秒
    • 要求停顿时间 500ms 以内
    • 高并发场景(如 Kafka 等消息中间件)

二、ZGC 收集器核心知识点

1. 基本特性与设计目标

  • 定位:JDK11 + 实验性低延迟收集器(JDK14 正式支持 Windows)
  • 核心目标
    • 支持 TB 级堆内存(最大 16TB,JDK13+)
    • 最大 GC 停顿时间≤10ms
    • 吞吐量降低不超过 15%
    • 停顿时间不随堆大小增长而增加
  • 关键技术:颜色指针、读屏障、NUMA 感知

2. 内存布局

  • 无分代设计:暂时不支持分代,后续版本计划优化
  • NUMA 优化:自动感知服务器 NUMA 架构,优先使用本地内存

3. 核心技术原理

(1)颜色指针
  • 优势
    1. Region 可立即释放,无需等待所有引用修正
    2. 仅需读屏障,减少内存屏障开销
    3. 扩展性强,可记录更多 GC 相关信息
  • 标记机制
    • 每次 GC 周期交替使用 Marked0/Marked1
    • 通过颜色位判断对象标记状态
(2)读屏障
  • 作用:在读取对象引用时触发,修正被移动对象的指针

  • 实现逻辑

    复制代码
    Object o = obj.fieldA; // 读取对象引用
    <读屏障> // 检查指针颜色
    if (指针为Bad Color) {
        修正指针到新地址(自愈能力)
    }
  • 性能开销:约 4% 的执行开销

4. 垃圾收集流程

  • 关键特性
    • 指针自愈:用户线程访问旧对象时自动修正指针
    • 重分配集:选择需回收的 Region 集合
    • 并发重映射:与下次标记阶段合并,减少遍历开销

5. 触发机制与参数配置

  • 触发机制

    1. 定时触发(默认禁用,ZCollectionInterval配置)
    2. 预热触发(堆达 10%、20%、30% 时,最多 3 次)
    3. 分配速率触发(基于正态分布预测内存耗尽时间)
    4. 主动触发(堆增长 10% 或超 5 分钟,且间隔超 49 倍 GC 时长)
  • 核心参数

    plaintext

    复制代码
    -XX:+UnlockExperimentalVMOptions -XX:+UseZGC // 启用ZGC
    -XX:ZHeapLimit=16T // 最大堆限制(JDK13+)
    -XX:ZCollectionInterval=300 // 定时触发间隔(秒)

6. 存在问题与解决方案

  • 主要问题
    • 浮动垃圾:GC 周期长(可能达分钟级),期间产生的新垃圾需下次回收
    • 无分代设计:"朝生夕死" 对象无法及时回收
  • 解决方案
    • 临时方案:增大堆容量,延长程序喘息时间
    • 根本方案:未来版本引入分代收集

三、垃圾收集器选择指南

  • JDK 默认收集器
    • JDK1.8:Parallel(年轻代 + 老年代)
    • JDK1.9+:G1 收集器

四、基础概念(面试高频)

1. 安全点(Safe Point)

  • 定义:线程状态确定的代码位置,GC 需等待所有线程到达安全点才能执行
  • 常见位置:方法返回前、方法调用后、异常抛出点、循环末尾
  • 实现机制:通过标志位轮询,线程主动在安全点挂起

2. 安全区域(Safe Region)

  • 适用场景:线程处于 Sleep / 中断状态,无法响应 GC 中断请求
  • 定义:一段引用关系不变的代码片段,任意位置开始 GC 都安全

3. 关键算法对比

算法 收集器 优点 缺点
复制算法 G1、ZGC(年轻代) 无内存碎片,效率高 需额外空间
标记 - 清理 CMS 无需复制,开销小 产生内存碎片
标记 - 整理 G1(整体)、ZGC 无内存碎片 整理阶段开销大
相关推荐
岳轩子2 小时前
JVM 运行时数据区域详解 第三节
jvm
2401_838472512 小时前
内存泄漏自动检测系统
开发语言·c++·算法
m0_706653232 小时前
基于C++的爬虫框架
开发语言·c++·算法
iRuriCatt2 小时前
智慧景区管理系统 | 计算机毕设项目
java·前端·spring boot·vue·毕设
diediedei2 小时前
嵌入式数据库C++集成
开发语言·c++·算法
君义_noip2 小时前
洛谷 P3388 【模板】割点(割顶)
c++·算法·图论·信息学奥赛·csp-s
xie0510_2 小时前
string模拟实现
开发语言·c++·算法
diediedei2 小时前
机器学习模型部署:将模型转化为Web API
jvm·数据库·python
m0_561359672 小时前
使用Python自动收发邮件
jvm·数据库·python