
JVM G1垃圾收集器 系统性知识体系(高频面试版)
一、G1垃圾收集器概述
1.1 定位与历史
- JDK 7u4正式引入,JDK 9成为默认垃圾收集器,替代CMS
- 面向服务端应用的低延迟垃圾收集器,同时兼顾吞吐量
- 是HotSpot虚拟机垃圾收集器发展史上的里程碑,标志着从"分代收集"向"区域化分代"的转变
1.2 核心设计目标
- 可预测的停顿时间模型:允许用户指定最大停顿时间(-XX:MaxGCPauseMillis)
- 高吞吐量:在满足低延迟的前提下,尽可能提高应用吞吐量
- 大堆支持:特别适合堆内存较大(4GB以上)的应用
- 避免全堆扫描:通过分区和Remembered Set技术,将回收范围限制在部分区域
1.3 核心思想
- 化整为零:将整个Java堆划分为多个大小相等的独立区域(Region)
- 收益优先:每次根据允许的停顿时间,优先回收垃圾最多的Region
- 保留分代思想:但不再物理隔离年轻代和老年代,而是逻辑上的划分
二、Region分区机制(G1的核心创新)
2.1 分区基本概念
- G1将整个Java堆(包括年轻代和老年代)划分为2048个大小相等的Region
- 每个Region的大小在1MB~32MB之间,且必须是2的幂次方
- 分区大小由JVM根据堆总大小自动计算,也可通过
-XX:G1HeapRegionSize手动指定
2.2 Region的类型
| 类型 | 说明 | 特点 |
|---|---|---|
| Eden Region | 年轻代Eden区 | 对象首次分配的区域,默认占堆的5% |
| Survivor Region | 年轻代Survivor区 | 分为S0和S1,默认占堆的1% |
| Old Region | 老年代区域 | 存放长期存活的对象 |
| Humongous Region | 巨型对象区域 | 专门存放超过Region大小50%的对象 |
2.3 巨型对象(Humongous Object)处理
- 定义:大小超过单个Region容量50%的对象
- 存储方式:直接分配在老年代的连续Humongous Region中
- 回收特点:
- 不会在年轻代GC中被回收
- 只能在Mixed GC或Full GC中被回收
- 由于需要连续空间,容易产生内存碎片
- JDK 8u40后优化了巨型对象的回收效率
2.4 Remembered Set(记忆集)
- 作用:解决跨Region引用问题,避免全堆扫描
- 实现:每个Region都有一个对应的Remembered Set
- 工作原理:
- 当一个Region中的对象引用了另一个Region中的对象时,会在被引用Region的Remembered Set中记录这个引用
- 垃圾回收时,只需要扫描对应Region的Remembered Set,而不需要扫描整个堆
- 维护代价:约占堆内存的1%~5%,是G1为实现部分回收付出的空间代价
三、Mixed GC机制(G1独有的回收方式)
3.1 为什么需要Mixed GC
- 传统的分代收集器:年轻代只回收年轻代,老年代只回收老年代
- G1的设计:Mixed GC不仅回收年轻代,还会回收一部分老年代Region
- 目的:在用户指定的停顿时间内,尽可能回收更多的垃圾,避免触发耗时的Full GC
3.2 Mixed GC的触发条件
当老年代占用率达到-XX:InitiatingHeapOccupancyPercent(默认45%)时,触发Mixed GC
3.3 回收集(Collection Set, CSet)
- 定义:Mixed GC中将要被回收的Region集合
- 组成:所有年轻代Region + 部分垃圾最多的老年代Region
- 选择算法:G1会计算每个老年代Region的"回收价值"(垃圾量/回收时间),优先选择回收价值最高的Region
- 数量限制:老年代Region的回收数量由
-XX:G1MixedGCCountTarget(默认8次)控制,即一次并发标记周期后,最多进行8次Mixed GC
3.4 Mixed GC的执行过程
- 并发标记阶段完成后,G1知道了所有Region的存活对象信息
- 根据用户指定的最大停顿时间,计算本次可以回收的Region数量
- 选择回收价值最高的老年代Region加入CSet
- 执行复制算法,将CSet中Region的存活对象复制到其他空闲Region
- 清空CSet中的所有Region,完成回收
四、G1完整回收流程
G1的垃圾回收过程分为四个主要阶段,其中并发标记是最复杂也是最重要的阶段。
4.1 阶段一:初始标记(Initial Marking)
- 执行方式:STW(Stop The World),但停顿时间很短
- 任务:
- 标记GC Roots能直接关联到的对象
- 修改TAMS(Top at Mark Start)指针,记录每个Region的当前顶部位置
- 触发时机:通常伴随着一次年轻代GC一起执行,因此不会产生额外的停顿
4.2 阶段二:并发标记(Concurrent Marking)
- 执行方式:与用户线程并发执行,不产生停顿
- 任务:
- 从GC Roots开始,遍历整个对象图,标记所有存活对象
- 处理并发过程中对象引用的变化(通过SATB算法)
- SATB(Snapshot At The Beginning)算法:
- 核心思想:在并发标记开始时,保存一份对象图的快照
- 作用:确保在并发标记过程中,所有在标记开始时存活的对象都能被正确标记
- 解决了CMS中"漏标"问题,但会产生一些浮动垃圾
4.3 阶段三:最终标记(Final Marking)
- 执行方式:STW,停顿时间较短
- 任务:
- 处理并发标记阶段遗留下来的SATB记录
- 修正并发标记过程中对象引用的变化
- 统计每个Region的存活对象数量和垃圾比例
4.4 阶段四:筛选回收(Live Data Counting and Evacuation)
- 执行方式:STW,停顿时间由用户指定
- 任务:
- 根据用户指定的最大停顿时间,选择回收价值最高的Region组成CSet
- 将CSet中Region的存活对象复制到其他空闲Region
- 清空CSet中的所有Region
- 更新Remembered Set
- 特点:这是G1真正执行垃圾回收的阶段,也是产生主要停顿的阶段
五、G1的关键特性与重要参数
5.1 关键特性
- 停顿时间预测:G1会根据历史回收数据,预测本次回收需要的时间,从而选择合适的回收集
- 无内存碎片:采用复制算法,回收后会整理内存,避免产生内存碎片
- 可伸缩性:能够很好地适应不同大小的堆内存和不同的硬件平台
- 并行与并发结合:多个GC线程并行执行回收任务,同时部分阶段与用户线程并发执行
5.2 重要调优参数
| 参数 | 默认值 | 说明 |
|---|---|---|
-XX:MaxGCPauseMillis |
200ms | 最大停顿时间目标,G1会尽量满足这个目标 |
-XX:G1HeapRegionSize |
自动计算 | 每个Region的大小,1MB~32MB,必须是2的幂 |
-XX:InitiatingHeapOccupancyPercent |
45% | 触发Mixed GC的老年代占用率阈值 |
-XX:G1MixedGCCountTarget |
8 | 一次并发标记周期后,最多执行的Mixed GC次数 |
-XX:G1OldCSetRegionThresholdPercent |
10% | 每次Mixed GC最多回收的老年代Region比例 |
-XX:+UseG1GC |
JDK9+默认 | 启用G1垃圾收集器 |
六、适用场景与不适用场景
6.1 适用场景(高频考点)
- 大堆应用:堆内存大于4GB的应用,G1的优势会更加明显
- 对延迟敏感的应用:如互联网后端服务、交易系统等,需要低延迟的垃圾回收
- 需要可预测停顿时间的应用:G1能够提供相对稳定的停顿时间,避免突然的长时间停顿
- 高吞吐量与低延迟兼顾的应用:G1在吞吐量和延迟之间取得了很好的平衡
6.2 不适用场景
- 小堆应用:堆内存小于2GB的应用,G1的额外开销(如Remembered Set)会比较明显
- 对吞吐量要求极高的应用:如果应用可以接受较长的停顿时间,追求极致的吞吐量,Parallel GC可能更合适
- 巨型对象过多的应用:G1对巨型对象的处理还不够完善,容易产生内存碎片和Full GC
七、G1与CMS的对比
| 特性 | G1 | CMS |
|---|---|---|
| 回收算法 | 复制算法(整体)+ 标记-整理(局部) | 标记-清除 |
| 内存碎片 | 无 | 有 |
| 停顿时间 | 可预测,相对稳定 | 不可预测,可能出现长时间停顿 |
| 堆大小 | 适合大堆(4GB以上) | 适合中小堆 |
| 并发阶段 | 并发标记 | 并发标记、并发清除 |
| Full GC触发 | 老年代不足、巨型对象分配失败 | 老年代不足、Concurrent Mode Failure |
| 吞吐量 | 较高 | 较低 |
八、高频面试考点总结
G1的核心思想是什么?
- 化整为零,将堆划分为多个Region
- 收益优先,优先回收垃圾最多的Region
- 保留分代思想,但逻辑上划分
G1的Region分区有什么特点?
- 大小相等,1MB~32MB,2的幂次方
- 分为Eden、Survivor、Old、Humongous四种类型
- 每个Region有对应的Remembered Set
什么是Mixed GC?它和Young GC、Full GC有什么区别?
- Mixed GC回收所有年轻代Region和部分老年代Region
- Young GC只回收年轻代
- Full GC回收整个堆,包括年轻代、老年代和方法区
G1的回收流程分为哪几个阶段?哪些阶段是STW的?
- 初始标记(STW)、并发标记(并发)、最终标记(STW)、筛选回收(STW)
G1如何实现可预测的停顿时间?
- 通过Region分区,将回收范围限制在部分区域
- 计算每个Region的回收价值,优先选择回收价值最高的Region
- 根据历史数据预测回收时间,控制回收集的大小
G1的适用场景是什么?
- 大堆应用(4GB以上)
- 对延迟敏感的应用
- 需要可预测停顿时间的应用
JVM G1垃圾收集器 面试问答卡片(高频必背版)
模块一:基础概念与核心思想
Q1:G1垃圾收集器的定位和发展历史是什么?
答:
- JDK 7u4正式引入,JDK 9成为默认垃圾收集器,替代CMS
- 面向服务端应用的低延迟收集器,同时兼顾吞吐量
- 是HotSpot从"物理分代"向"区域化逻辑分代"转变的里程碑
Q2:G1的三个核心设计目标是什么?
答:
- 可预测的停顿时间模型:允许用户指定最大停顿时间(
-XX:MaxGCPauseMillis) - 高吞吐量:在满足低延迟的前提下最大化应用执行效率
- 大堆支持:特别适合4GB以上的大堆应用,避免全堆扫描
Q3:G1的核心设计思想是什么?
答:
- 化整为零:将整个Java堆划分为多个大小相等的独立Region
- 收益优先:每次根据允许的停顿时间,优先回收垃圾最多的Region
- 保留分代思想:但不再物理隔离年轻代和老年代,而是逻辑上的划分
模块二:Region分区机制(核心创新)
Q4:G1的Region分区有什么基本特点?
答:
- 将整个堆(年轻代+老年代)划分为2048个大小相等的Region
- 单个Region大小在1MB~32MB之间,且必须是2的幂次方
- 分区大小由JVM根据堆总大小自动计算,也可通过
-XX:G1HeapRegionSize手动指定
Q5:G1的Region分为哪几种类型?各自的作用是什么?
答:
| 类型 | 作用 |
|---|---|
| Eden Region | 年轻代,对象首次分配的区域 |
| Survivor Region | 年轻代,存放Minor GC后存活的对象 |
| Old Region | 老年代,存放长期存活的对象 |
| Humongous Region | 巨型对象区,专门存放超过Region大小50%的对象 |
Q6:G1如何处理巨型对象(Humongous Object)?
答:
- 定义:大小超过单个Region容量50%的对象
- 分配:直接分配在老年代的连续Humongous Region中
- 回收:只能在Mixed GC或Full GC中被回收,不会在Young GC中回收
- 问题:需要连续空间,容易产生内存碎片;JDK 8u40后优化了回收效率
Q7:Remembered Set(记忆集)的作用是什么?
答:
- 解决跨Region引用问题,避免垃圾回收时扫描整个堆
- 每个Region都有一个对应的Remembered Set
- 当A Region的对象引用B Region的对象时,会在B Region的Remembered Set中记录这个引用
- 回收时只需扫描对应Region的Remembered Set,而非全堆
- 空间代价:约占堆内存的1%~5%
模块三:Mixed GC机制(G1独有)
Q8:什么是Mixed GC?为什么G1需要Mixed GC?
答:
- 定义:G1独有的回收方式,同时回收所有年轻代Region和部分垃圾最多的老年代Region
- 为什么需要:
- 传统分代收集器只能单独回收年轻代或老年代
- G1通过Mixed GC在用户指定的停顿时间内回收更多垃圾
- 避免触发耗时的Full GC
Q9:Mixed GC的触发条件是什么?
答:
当老年代占用率达到-XX:InitiatingHeapOccupancyPercent(默认45%)时,触发Mixed GC
Q10:什么是回收集(Collection Set, CSet)?
答:
- 定义:Mixed GC中将要被回收的Region集合
- 组成:所有年轻代Region + 部分回收价值最高的老年代Region
- 选择算法:计算每个老年代Region的"回收价值"(垃圾量/回收时间),优先选择价值最高的
- 数量限制:由
-XX:G1MixedGCCountTarget(默认8次)控制,一次并发标记后最多执行8次Mixed GC
模块四:完整回收流程
Q11:G1的垃圾回收流程分为哪几个阶段?哪些阶段是STW的?
答:
- 初始标记(STW,停顿极短)
- 并发标记(与用户线程并发,无停顿)
- 最终标记(STW,停顿较短)
- 筛选回收(STW,主要停顿阶段)
Q12:初始标记阶段做了什么?
答:
- 执行方式:STW,通常伴随一次Young GC执行,无额外停顿
- 核心任务:
- 标记GC Roots能直接关联到的对象
- 修改TAMS(Top at Mark Start)指针,记录每个Region的当前顶部位置
Q13:并发标记阶段做了什么?SATB算法的作用是什么?
答:
- 执行方式:与用户线程并发执行
- 核心任务:从GC Roots开始遍历整个对象图,标记所有存活对象
- SATB(Snapshot At The Beginning)算法:
- 核心思想:在并发标记开始时保存一份对象图的快照
- 作用:解决并发标记过程中的"漏标"问题
- 代价:会产生少量浮动垃圾
Q14:最终标记阶段做了什么?
答:
- 执行方式:STW,停顿时间较短
- 核心任务:
- 处理并发标记阶段遗留的SATB记录
- 修正并发过程中对象引用的变化
- 统计每个Region的存活对象数量和垃圾比例
Q15:筛选回收阶段做了什么?
答:
- 执行方式:STW,停顿时间由用户指定的最大停顿时间控制
- 核心任务:
- 根据最大停顿时间目标,选择回收价值最高的Region组成CSet
- 将CSet中Region的存活对象复制到其他空闲Region
- 清空CSet中的所有Region
- 更新Remembered Set
模块五:关键特性与调优参数
Q16:G1如何实现可预测的停顿时间?
答:
- 通过Region分区,将回收范围限制在部分区域而非全堆
- 计算每个Region的回收价值(垃圾量/回收时间),优先选择价值最高的
- 根据历史回收数据预测本次回收所需时间,精确控制回收集的大小
Q17:G1最重要的5个调优参数是什么?
答:
| 参数 | 默认值 | 作用 |
|---|---|---|
-XX:MaxGCPauseMillis |
200ms | 最大停顿时间目标,G1会尽量满足 |
-XX:G1HeapRegionSize |
自动计算 | 单个Region大小,1MB~32MB,2的幂 |
-XX:InitiatingHeapOccupancyPercent |
45% | 触发Mixed GC的老年代占用率阈值 |
-XX:G1MixedGCCountTarget |
8 | 一次并发标记后最多执行的Mixed GC次数 |
-XX:+UseG1GC |
JDK9+默认 | 启用G1垃圾收集器 |
模块六:适用场景与对比
Q18:G1的适用场景是什么?(高频必背)
答:
- 大堆应用:堆内存大于4GB的应用,G1优势明显
- 对延迟敏感的应用:如互联网后端、交易系统、支付系统等
- 需要可预测停顿时间的应用:避免突然的长时间卡顿
- 吞吐量与延迟兼顾的应用:在两者之间取得了很好的平衡
Q19:G1的不适用场景是什么?
答:
- 小堆应用:堆内存小于2GB时,G1的额外开销(如Remembered Set)会比较明显
- 极致吞吐量优先的应用:如果可以接受较长停顿,Parallel GC吞吐量更高
- 巨型对象过多的应用:G1对巨型对象处理不够完善,容易产生碎片和Full GC
Q20:G1和CMS垃圾收集器的核心区别是什么?
答:
| 特性 | G1 | CMS |
|---|---|---|
| 回收算法 | 复制算法(整体)+ 标记-整理(局部) | 标记-清除 |
| 内存碎片 | 无 | 有 |
| 停顿时间 | 可预测,相对稳定 | 不可预测,可能出现长时间停顿 |
| 堆大小 | 适合大堆(4GB以上) | 适合中小堆 |
| 回收范围 | 部分Region | 整个老年代 |
| Full GC触发 | 老年代不足、巨型对象分配失败 | 老年代不足、Concurrent Mode Failure |
| 吞吐量 | 较高 | 较低 |
JVM G1垃圾收集器 面试问答卡片(进阶版)
模块七:G1常见问题排查(生产高频)
Q21:G1频繁触发Full GC的常见原因有哪些?如何排查?
答:
- 现象:GC日志中频繁出现
Full GC (Allocation Failure)或Full GC (Ergonomics),应用卡顿严重 - 常见原因及排查:
- 巨型对象过多
- 排查:查看GC日志中
Humongous Allocation的次数 - 解决:增大
-XX:G1HeapRegionSize,减少巨型对象数量;优化代码避免创建过大对象
- 排查:查看GC日志中
- 老年代增长过快
- 排查:查看GC日志中老年代占用率变化
- 解决:降低
-XX:InitiatingHeapOccupancyPercent,提前触发Mixed GC
- Mixed GC回收效率不足
- 排查:查看每次Mixed GC回收的老年代Region数量
- 解决:增加
-XX:G1MixedGCCountTarget,减少每次Mixed GC的老年代回收量
- 内存泄漏
- 排查:使用jmap、jhat或MAT分析堆转储文件
- 解决:修复代码中的内存泄漏问题
- 巨型对象过多
Q22:G1 Mixed GC耗时过长的原因有哪些?如何优化?
答:
- 现象:Mixed GC的STW时间超过
-XX:MaxGCPauseMillis设定的目标 - 常见原因及优化:
- 回收集(CSet)过大
- 原因:老年代垃圾过多,G1为了回收更多垃圾扩大了CSet
- 优化:降低
-XX:G1OldCSetRegionThresholdPercent(默认10%),限制每次Mixed GC回收的老年代比例
- 存活对象过多
- 原因:CSet中Region的存活对象比例高,复制耗时久
- 优化:调整
-XX:MaxTenuringThreshold,让对象尽早晋升到老年代
- Remembered Set扫描耗时
- 原因:跨Region引用过多,扫描Remembered Set耗时
- 优化:减少跨代引用,增大
-XX:G1RSetSparseRegionEntries
- GC线程数不足
- 原因:GC线程数设置过少,并行回收效率低
- 优化:调整
-XX:ParallelGCThreads,通常设置为CPU核心数
- 回收集(CSet)过大
Q23:G1中巨型对象(Humongous Object)会导致哪些问题?
答:
- 内存碎片:巨型对象需要连续的Region空间,容易产生内存碎片
- 提前触发Full GC:当没有足够的连续Region分配巨型对象时,会直接触发Full GC
- 回收效率低:巨型对象只能在Mixed GC或Full GC中被回收,不能在Young GC中回收
- 占用老年代空间:巨型对象直接分配在老年代,会加速老年代的占用
- 解决方案:
- 增大
-XX:G1HeapRegionSize,使更多对象不再是巨型对象 - 优化代码,将大对象拆分为多个小对象
- 避免频繁创建和销毁巨型对象
- 增大
Q24:G1停顿时间超标(超过MaxGCPauseMillis)如何排查?
答:
- 排查步骤:
- 查看GC日志,确定是哪个阶段的停顿时间过长
- 如果是筛选回收阶段:
- 检查CSet大小是否过大
- 检查存活对象比例是否过高
- 检查Remembered Set扫描耗时
- 如果是最终标记阶段:
- 检查并发标记阶段是否产生了大量SATB记录
- 检查用户线程在并发阶段的引用修改频率
- 如果是初始标记阶段:
- 通常伴随Young GC,检查Young GC本身是否耗时过长
- 通用优化:
- 适当降低
-XX:MaxGCPauseMillis的目标值(不要过低) - 增加GC线程数
- 调整老年代触发Mixed GC的阈值
- 适当降低
Q25:G1 Remembered Set占用内存过高怎么办?
答:
- 现象:JVM进程占用内存远大于堆内存设置,通过jstat查看
RSet占用过高 - 原因:跨Region引用过多,导致每个Region的Remembered Set都很大
- 解决方案:
- 增大
-XX:G1HeapRegionSize,减少Region数量,从而减少跨Region引用 - 调整
-XX:G1RSetUpdatingPauseTimePercent(默认10%),限制Remembered Set更新占用的停顿时间 - 优化代码,减少对象之间的跨代引用
- 适当降低堆内存大小
- 增大
Q26:G1并发标记周期过长会导致什么问题?
答:
- 问题:
- 老年代在并发标记期间继续增长,可能在标记完成前就被占满,触发Full GC
- 浮动垃圾增多,降低回收效率
- 原因:
- 堆内存过大,存活对象过多
- 并发标记线程数不足
- 用户线程CPU占用过高,抢占了GC线程的资源
- 解决方案:
- 增加
-XX:ConcGCThreads,提高并发标记线程数 - 降低
-XX:InitiatingHeapOccupancyPercent,提前触发并发标记 - 优化应用代码,降低CPU使用率
- 增加
模块八:生产环境调优案例(实战高频)
Q27:16GB堆内存的互联网后端服务基础调优案例
答:
- 业务背景:电商订单系统,日均订单100万,峰值QPS 5000,堆内存16GB
- 问题现象:平均停顿时间300ms,峰值时达到500ms,偶尔出现Full GC
- 调优参数:
-Xms16g -Xmx16g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1HeapRegionSize=16m # 16GB堆/16MB=1024个Region,避免过多Region -XX:InitiatingHeapOccupancyPercent=35 # 提前触发Mixed GC -XX:G1MixedGCCountTarget=10 # 增加Mixed GC次数,减少每次回收量 -XX:ParallelGCThreads=8 # 8核CPU -XX:ConcGCThreads=2 - 调优效果:平均停顿时间降至120ms,峰值不超过200ms,Full GC消失
Q28:金融交易系统低延迟调优案例
答:
- 业务背景:证券交易系统,要求单次交易延迟<10ms,堆内存8GB
- 问题现象:GC停顿时间波动大,偶尔出现200ms以上的停顿
- 调优参数:
-Xms8g -Xmx8g -XX:+UseG1GC -XX:MaxGCPauseMillis=50 # 严格控制停顿时间 -XX:G1HeapRegionSize=8m -XX:InitiatingHeapOccupancyPercent=30 # 更早触发Mixed GC -XX:G1OldCSetRegionThresholdPercent=5 # 每次只回收5%的老年代Region -XX:G1MixedGCCountTarget=16 # 增加Mixed GC次数 -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=30 # 增大年轻代比例,减少Young GC频率 -XX:G1MaxNewSizePercent=40 - 调优效果:99.9%的GC停顿时间<50ms,满足交易系统低延迟要求
Q29:巨型对象过多导致频繁Full GC的调优案例
答:
- 业务背景:大数据处理系统,频繁处理10MB~20MB的字节数组,堆内存32GB
- 问题现象:每10分钟触发一次Full GC,GC日志中大量
Humongous Allocation - 调优前参数:
-Xms32g -Xmx32g -XX:+UseG1GC -XX:G1HeapRegionSize=8m # 10MB对象成为巨型对象 - 调优后参数:
-Xms32g -Xmx32g -XX:+UseG1GC -XX:G1HeapRegionSize=32m # 10MB对象不再是巨型对象 -XX:InitiatingHeapOccupancyPercent=40 - 调优效果:Full GC频率降至每天1次,系统吞吐量提升30%
Q30:高吞吐量批处理系统G1调优案例
答:
- 业务背景:离线数据批处理系统,每天处理TB级数据,追求高吞吐量
- 问题现象:使用Parallel GC时,单次Full GC停顿时间超过10秒
- 调优参数:
-Xms64g -Xmx64g -XX:+UseG1GC -XX:MaxGCPauseMillis=500 # 适当放宽停顿时间,提高吞吐量 -XX:G1HeapRegionSize=32m -XX:InitiatingHeapOccupancyPercent=50 # 延迟触发Mixed GC -XX:G1MixedGCCountTarget=4 # 减少Mixed GC次数 -XX:ParallelGCThreads=16 # 16核CPU -XX:ConcGCThreads=4 - 调优效果:单次GC停顿时间控制在500ms以内,系统整体吞吐量提升20%
模块九:G1调优最佳实践
Q31:G1调优的基本原则是什么?
答:
- 不要过度调优:G1的自适应机制已经很完善,优先使用默认参数
- 优先调整堆大小和Region大小:这是影响G1性能最关键的两个参数
- 不要设置年轻代大小:让G1自动调整年轻代大小,以满足停顿时间目标
- 基于GC日志调优:所有调优都必须基于GC日志的数据分析
- 小步迭代:每次只调整一个参数,观察效果后再进行下一步调整
Q32:G1调优的一般步骤是什么?
答:
- 开启GC日志:添加参数
-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps - 分析GC日志:使用GCEasy、GCViewer等工具分析GC日志
- 确定瓶颈:找出是停顿时间过长、吞吐量低还是频繁Full GC
- 针对性调优:根据瓶颈调整对应的参数
- 验证效果:在测试环境验证调优效果,然后逐步推广到生产环境