【大白话说Java面试题 第66题】【JVM篇】第26题:介绍一下 G1 垃圾收集器?
PDF大白话说Java面试题 — 02-JVM篇第26题介绍一下 G1 垃圾收集器回答核心考点G1Garbage First是JDK 9的默认垃圾收集器设计目标是替代CMS在大堆内存≥4GB场景下实现可预测的停顿时间同时避免内存碎片。面试需掌握其Region布局、停顿模型、与CMS的本质区别。1. G1 的核心设计思想特性说明Region化堆内存将堆划分为多个大小相等的Region1~32MB默认2048个每个Region可动态扮演Eden、Survivor、Old、Humongous大对象角色停顿预测模型基于历史数据每个Region的回收耗时选择**高收益Region集合CSet**回收使停顿时间可控增量式回收每次只回收部分Region而非全堆避免长时间STW全局并发标记并发标记存活对象最终通过筛选回收阶段复制存活对象到新Region彻底消除碎片2. G1 的内存布局关键区别与传统分代GC对比传统Parallel/CMS物理连续分区Eden、S0、S1、OldG1逻辑分代 物理Region隔离某Region可以从未分代动态切换大对象Humongous Region对象大小 Region大小的50%存放在连续的Humongous Region中H区回收时效率低需避免过多大对象3. G1 的工作阶段面试详版阶段类型主要动作是否STW备注初始标记Young GC期间附属标记GC Roots直接可达对象是借用Young GC停顿几乎无额外开销并发标记并发从GC Roots遍历对象图计算每个Region存活对象否标记过程中应用线程继续运行最终标记并发短暂STW处理SATBSnapshot-At-The-Beginning漏标对象是修正并发标记期间的引用变化筛选回收混合模式选择回收价值最高的RegionCSet复制存活对象是可并行停顿时间由MaxGCPauseMillis控制Full GC后备单线程Serial Old回收全堆是很长当并发回收赶不上对象分配时触发关键点SATBSnapshot-At-The-BeginningG1通过写屏障维护并发标记开始时对象图的快照防止漏标。Mixed GC筛选回收阶段会同时回收年轻代部分老年代Region。4. G1 停顿时间模型面试核心参数-XX:MaxGCPauseMillis200# 目标200ms默认值不是硬性保证G1会尽量逼近-XX:GCPauseIntervalMillis# 停顿间隔默认未设置实现机制G1会记录每个Region的历史回收耗时平均、标准差等年轻代大小动态调整若历史停顿时间 目标缩小年轻代否则扩大筛选回收时按垃圾/回收耗时比对Region排序从高到低选入CSet直到预估总时间接近目标值误区设置MaxGCPauseMillis太小如10ms会导致年轻代极小Young GC频繁吞吐下降。5. G1 vs CMS 深度对比对比维度G1CMS堆布局Region化逻辑分代物理连续分代EdenS0S1Old碎片问题无碎片复制整理严重碎片标记-清除停顿时间可预测可控制默认200ms不可控随老年代碎片恶化Full GC触发并发回收赶不上分配时碎片导致晋升失败/并发模式失败CPU敏感度中等高并发标记占CPU内存占用每个Region有Remembered SetRS额外占用5%~10%堆内存较低大对象处理Humongous Region效率低直接进老年代易导致碎片JDK版本JDK 7u4引入JDK 9默认JDK 9废弃JDK 14移除6. G1 常用调优参数参数含义建议值风险提示-XX:MaxGCPauseMillis目标停顿时间100~300ms太小导致频繁GC-XX:G1HeapRegionSizeRegion大小自动1/2/4/8/16/32MB手动设需是2的幂-XX:InitiatingHeapOccupancyPercent触发并发标记的老年代占用比例默认45%过低频繁并发标记过高易Full GC-XX:G1NewSizePercent年轻代最小值占堆百分比默认5%太小导致频繁Young GC-XX:G1MaxNewSizePercent年轻代最大值默认60%太大可能导致老年代回收赶不上-XX:ParallelGCThreads并行GC线程数默认CPU数5/8容器内需设置≤CPU核数-XX:ConcGCThreads并发GC线程数默认ParallelGCThreads的1/4并发标记阶段占CPU7. G1 典型问题与排查问题1Mixed GC后仍有大量老年代内存未回收持续Full GC根因InitiatingHeapOccupancyPercent过大导致并发标记触发晚老年代堆积过多解决调小至35~40%或增大MaxGCPauseMillis问题2Humongous对象分配导致频繁Full GC根因大对象Region 50%分配后回收代价高解决应用层拆分大对象或增大Region-XX:G1HeapRegionSize32m问题3RSRemembered Set占用内存过高根因Region间引用复杂跨区引用多解决正常现象限制G1堆内存16GBJDK 8之前或升级JDK优化了RS压缩8. 面试官追问示例Q1G1 一定比 CMS 好吗A不是。CMS在堆内存4GB、停顿不敏感的场景仍然高效。G1的RS维护占用额外内存~10%小堆上得不偿失。Q2G1 的 Mixed GC 频率如何控制A由InitiatingHeapOccupancyPercent控制当老年代占用超过此阈值时触发并发标记标记完成后触发Mixed GC。Mixed GC会持续多次每次回收部分老年代Region。Q3G1 能完全避免 Full GC 吗A不能。典型情况并发模式失败老年代未标记完就满了晋升失败Survivor/老年代Region无空间放晋升对象大对象分配找不到连续Humongous RegionQ4G1 中 Young GC 也是 STW 的为什么说 G1 低延迟A因为Young GC虽然STW但G1通过动态调整年轻代大小让每次Young GC停顿时间可控接近MaxGCPauseMillis。而Parallel GC年轻代固定停顿可能更长。Q5G1 适用于多大堆内存A官方推荐6GB~64GB。大于64GB推荐ZGC停顿10ms小于6GB可用Parallel或G1但RS内存开销明显。面试官想要的满分总结“G1是Region化、增量式、可预测停顿的垃圾收集器通过复制整理消除碎片。核心机制包括堆分为等大小Region、Remembered Set避免全局扫描、SATB保证并发标记正确性、根据历史数据选择高收益Region回收。适用堆4~64GB调优核心是MaxGCPauseMillis默认200ms和InitiatingHeapOccupancyPercent默认45%。与CMS相比G1无碎片、停顿可控但内存占用略高。大堆场景下G1优于CMS超大堆64GB应选ZGC/Shenandoah。”觉得对您有帮助麻烦点点关注啦您的关注是我创作的最大动力~