【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》)

【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》) 文章目录JVM CMS垃圾收集器 系统性知识体系总结一、CMS概述与定位二、CMS核心原理2.1 并发执行的本质2.2 三色标记法并发标记的基础2.3 增量更新Incremental Update解决方案三、CMS完整回收流程7个阶段阶段1初始标记Initial Mark- STW阶段2并发标记Concurrent Mark- 并发阶段3并发预清理Concurrent Preclean- 并发阶段4并发可中断预清理Concurrent Abortable Preclean- 并发阶段5最终标记Final Remark- STW阶段6并发清除Concurrent Sweep- 并发阶段7并发重置Concurrent Reset- 并发四、CMS核心优缺点分析4.1 显著优点4.2 致命缺点五、CMS被废弃的根本原因5.1 设计缺陷无法根本解决5.2 G1收集器的全面超越5.3 维护成本过高六、补充知识CMS关键参数调优七、总结CMS垃圾收集器 面试问答卡片可直接背诵一、基础概念类Q1什么是CMS垃圾收集器它的设计目标和适用场景是什么Q2CMS和传统收集器如Serial Old最本质的区别是什么二、核心原理类Q3CMS使用什么算法实现并发标记它将对象分为哪几类Q4并发标记阶段会产生什么核心问题CMS是如何解决的三、回收流程类Q5CMS完整的回收流程分为哪7个阶段哪些是STW阶段Q6请简述CMS每个核心阶段的主要任务和特点四、优缺点类Q7CMS有哪些显著的优点Q8CMS有哪些致命的缺点高频考点Q9什么是CMS的并发模式失败它会导致什么后果五、废弃原因类Q10CMS为什么会被废弃它在哪个JDK版本被标记为废弃哪个版本被完全移除六、调优参数类Q11列举5个CMS最常用的调优参数及其作用CMS vs G1 垃圾收集器 对比面试问答卡片高频考点一、基础定位与核心差异类Q1CMS和G1最根本的区别是什么Q2CMS和G1分别在哪个JDK版本成为默认收集器二、核心原理对比类Q3CMS和G1使用的核心垃圾回收算法有什么不同Q4CMS和G1解决并发标记对象丢失问题的方案有什么不同三、回收流程对比类Q5CMS和G1的回收流程有什么本质区别Q6什么是G1的Mixed GC它和CMS的老年代GC有什么不同四、性能与问题对比类Q7CMS和G1在停顿时间方面有什么差异Q8CMS的并发模式失败和G1的疏散失败有什么区别Q9CMS和G1在处理大对象方面有什么不同五、适用场景与调优对比类Q10CMS和G1分别适用于什么场景Q11CMS和G1最核心的调优参数分别是什么六、总结对比表面试速记JVM CMS垃圾收集器 系统性知识体系总结一、CMS概述与定位Concurrent Mark Sweep并发标记清除是HotSpot虚拟机在JDK 1.5时期推出的并发低延迟垃圾收集器也是JVM历史上第一个真正意义上实现垃圾回收线程与用户线程并发执行的收集器。设计目标最短回收停顿时间Stop-The-World, STW优先满足响应速度要求适用场景互联网Web应用、B/S系统、桌面GUI应用等对用户体验敏感的系统作用范围老年代需配合年轻代的Serial或ParNew收集器使用核心算法标记-清除Mark-Sweep算法并发版本二、CMS核心原理2.1 并发执行的本质CMS通过将耗时最长的标记和清除阶段与用户线程并发执行大幅缩短单次STW时间。它使用多线程并行处理垃圾回收任务充分利用多核CPU资源。2.2 三色标记法并发标记的基础CMS使用三色标记法实现并发标记将对象分为三类白色未被垃圾收集器访问过初始状态最终会被回收灰色已被访问过但至少有一个引用未被扫描黑色已被访问过且所有引用都已扫描完毕存活对象并发标记的核心问题用户线程在标记过程中修改引用关系可能导致对象丢失原本存活的对象被误标为白色。2.3 增量更新Incremental Update解决方案CMS采用增量更新算法解决并发标记时的对象丢失问题当一个黑色对象新增了对白色对象的引用时将这个黑色对象重新标记为灰色在最终重新标记阶段会重新扫描所有灰色对象确保所有存活对象都被正确标记原理破坏了黑色对象不会引用白色对象的对象丢失条件保证了标记的准确性。三、CMS完整回收流程7个阶段CMS的回收过程分为4个STW阶段和3个并发阶段按执行顺序排列阶段1初始标记Initial Mark- STW耗时极短毫秒级任务只标记GC Roots直接关联的对象特点单线程执行JDK 1.6后改为多线程停顿时间与堆大小无关只与GC Roots数量有关阶段2并发标记Concurrent Mark- 并发耗时最长与堆中存活对象数量成正比任务从初始标记的对象出发遍历整个对象图标记所有存活对象特点与用户线程完全并发执行不产生停顿但标记结果可能不准确用户线程修改了引用阶段3并发预清理Concurrent Preclean- 并发耗时较短任务处理并发标记阶段产生的脏卡Dirty Card标记从年轻代晋升到老年代的对象提前处理部分引用变化减轻后续重新标记阶段的负担特点可通过参数控制执行时间目的是缩短最终重新标记的STW时间阶段4并发可中断预清理Concurrent Abortable Preclean- 并发耗时可配置默认最多5秒任务与并发预清理类似但可以被中断特点等待年轻代发生Minor GC因为年轻代GC后老年代的引用会更稳定能进一步减少重新标记的工作量阶段5最终标记Final Remark- STW耗时中等比初始标记长但远短于并发标记任务修正并发标记阶段因用户线程修改引用导致的标记错误重新扫描所有GC Roots处理增量更新记录的引用变化特点多线程并行执行是CMS整个回收过程中第二长的停顿阶段6并发清除Concurrent Sweep- 并发耗时较长与垃圾数量成正比任务清除所有被标记为垃圾的对象释放内存空间特点与用户线程并发执行不移动存活对象直接回收垃圾内存阶段7并发重置Concurrent Reset- 并发耗时极短任务重置CMS收集器的内部数据结构为下一次垃圾回收做准备特点与用户线程并发执行不影响应用性能四、CMS核心优缺点分析4.1 显著优点低延迟将90%以上的工作放在并发阶段执行STW时间极短通常在几十毫秒以内高并发充分利用多核CPU资源垃圾回收与应用程序同时运行响应迅速特别适合对用户体验要求高的交互式应用成熟稳定经过多年生产环境验证调优经验丰富4.2 致命缺点CPU资源消耗大并发阶段会占用大量CPU线程默认占用CPU核心数的1/4在CPU核心数较少的服务器上如2核会严重影响应用程序的吞吐量当CPU负载较高时并发回收的效率会急剧下降内存碎片问题基于标记-清除算法回收后会产生大量不连续的内存碎片碎片过多会导致大对象无法分配提前触发Full GC虽然提供了-XX:UseCMSCompactAtFullCollection参数进行压缩但压缩阶段会产生长时间STW并发模式失败Concurrent Mode Failure并发清除阶段用户线程仍在运行会产生新的垃圾称为浮动垃圾如果老年代剩余空间不足以容纳浮动垃圾会触发并发模式失败此时CMS会退化为Serial Old收集器进行单线程Full GC产生极长的STW停顿可能长达数秒甚至数十秒无法处理浮动垃圾并发标记和清除阶段产生的新垃圾只能等到下一次GC才能回收因此CMS需要预留一部分内存空间给浮动垃圾使用默认老年代使用率达到68%时触发GC预留空间过小会导致并发模式失败过大则会浪费内存五、CMS被废弃的根本原因CMS在JDK 9中被标记为废弃Deprecated在JDK 14中被完全移除主要原因如下5.1 设计缺陷无法根本解决内存碎片问题这是标记-清除算法的固有缺陷无论如何调优都无法彻底解决并发模式失败风险始终存在退化为Serial Old的可能这是生产环境的重大隐患CPU资源占用在低配置服务器上表现极差无法适应现代多核CPU的发展趋势5.2 G1收集器的全面超越G1Garbage-First收集器在JDK 7中正式推出在JDK 9中成为默认收集器全面取代了CMS统一收集年轻代和老年代不需要配合其他收集器使用简化了JVM配置基于Region的内存布局将堆划分为多个大小相等的Region解决了内存碎片问题可预测的停顿时间模型用户可以指定最大停顿时间G1会尽量满足并行与并发结合既利用多核CPU又保持低延迟整体标记-整理局部复制兼顾了吞吐量和内存利用率5.3 维护成本过高CMS的代码非常复杂维护难度大随着JVM的发展CMS与其他新特性如ZGC、Shenandoah的兼容性越来越差Oracle将开发资源集中在更先进的G1、ZGC和Shenandoah收集器上六、补充知识CMS关键参数调优参数作用默认值-XX:UseConcMarkSweepGC启用CMS收集器JDK 8及之前非服务器模式默认-XX:ParallelGCThreads并行阶段的线程数CPU核心数-XX:ConcGCThreads并发阶段的线程数ParallelGCThreads/4-XX:CMSInitiatingOccupancyFraction老年代使用率达到多少时触发GC68%-XX:UseCMSCompactAtFullCollectionFull GC时进行内存压缩JDK 8默认开启-XX:CMSFullGCsBeforeCompaction多少次Full GC后进行一次压缩0每次都压缩-XX:CMSParallelRemarkEnabled启用并行最终标记默认开启七、总结CMS是JVM垃圾回收技术发展史上的里程碑式产品它首次实现了并发垃圾回收解决了传统收集器停顿时间过长的问题为互联网应用的发展做出了巨大贡献。然而由于其基于标记-清除算法的固有缺陷以及G1等新一代收集器的出现CMS最终被淘汰。但CMS的设计思想并发标记、增量更新等对后续收集器的发展产生了深远影响是学习JVM垃圾回收机制不可或缺的重要内容。CMS垃圾收集器 面试问答卡片可直接背诵一、基础概念类Q1什么是CMS垃圾收集器它的设计目标和适用场景是什么ACMS全称Concurrent Mark Sweep并发标记清除是HotSpot在JDK1.5推出的第一个真正意义上的并发低延迟收集器设计目标最短STW停顿时间优先保证响应速度适用场景互联网Web应用、B/S系统、桌面GUI等对用户体验敏感的系统作用范围仅老年代必须配合年轻代的Serial或ParNew收集器使用核心算法并发版本的标记-清除算法Q2CMS和传统收集器如Serial Old最本质的区别是什么A传统收集器Serial Old、Parallel Old在垃圾回收时全程STW停顿时间与堆大小成正比而CMS将90%以上的耗时工作标记、清除与用户线程并发执行仅在几个关键阶段短暂停顿大幅降低了单次停顿时间。二、核心原理类Q3CMS使用什么算法实现并发标记它将对象分为哪几类ACMS使用三色标记法实现并发标记将对象分为三类白色未被收集器访问过初始状态最终会被回收灰色已被访问过但至少有一个引用未扫描完成黑色已被访问过且所有引用都已扫描完毕存活对象Q4并发标记阶段会产生什么核心问题CMS是如何解决的A核心问题对象丢失用户线程在标记过程中修改引用关系导致原本存活的对象被误标为白色解决方案增量更新Incremental Update算法当一个黑色对象新增了对白色对象的引用时将该黑色对象重新标记为灰色在最终重新标记阶段重新扫描所有灰色对象确保所有存活对象都被正确标记原理破坏了黑色对象不会引用白色对象的对象丢失必要条件三、回收流程类Q5CMS完整的回收流程分为哪7个阶段哪些是STW阶段ACMS回收流程按顺序分为7个阶段其中4个STW阶段3个并发阶段✅初始标记STW极短⚡ 并发标记并发最长⚡ 并发预清理并发较短⚡ 并发可中断预清理并发可配置✅最终标记STW中等⚡ 并发清除并发较长⚡ 并发重置并发极短Q6请简述CMS每个核心阶段的主要任务和特点A初始标记只标记GC Roots直接关联的对象多线程执行停顿时间与堆大小无关只与GC Roots数量有关并发标记从初始标记对象出发遍历整个对象图与用户线程完全并发标记结果可能不准确并发预清理处理并发标记产生的脏卡标记从年轻代晋升的对象目的是减轻最终标记的负担并发可中断预清理与预清理类似但可中断等待年轻代Minor GC以进一步减少重新标记工作量最终标记修正并发标记阶段的标记错误重新扫描GC Roots和增量更新记录是CMS第二长的停顿并发清除清除所有标记为垃圾的对象不移动存活对象直接回收内存并发重置重置内部数据结构为下一次GC做准备四、优缺点类Q7CMS有哪些显著的优点A低延迟绝大多数工作并发执行STW时间通常控制在几十毫秒以内高并发充分利用多核CPU资源垃圾回收与应用同时运行响应迅速特别适合交互式应用提升用户体验成熟稳定经过多年生产环境验证调优经验丰富Q8CMS有哪些致命的缺点高频考点ACPU资源消耗大并发阶段默认占用1/4的CPU核心数低配置服务器上会严重影响吞吐量内存碎片问题基于标记-清除算法回收后产生大量不连续碎片导致大对象无法分配提前触发Full GC并发模式失败风险并发清除阶段产生的浮动垃圾如果超出预留内存CMS会退化为Serial Old单线程收集器产生极长STW停顿数秒甚至数十秒无法处理浮动垃圾并发阶段产生的新垃圾只能等到下一次GC回收因此需要预留部分内存造成浪费Q9什么是CMS的并发模式失败它会导致什么后果A定义在并发清除阶段用户线程仍在运行并产生新的垃圾浮动垃圾如果老年代剩余空间不足以容纳这些浮动垃圾就会触发并发模式失败后果CMS会立即停止所有并发回收线程退化为Serial Old单线程收集器对整个老年代进行Full GC此时会产生极长的STW停顿是生产环境的重大隐患五、废弃原因类Q10CMS为什么会被废弃它在哪个JDK版本被标记为废弃哪个版本被完全移除A版本JDK 9中被标记为Deprecated废弃JDK 14中被完全移除根本原因固有设计缺陷无法解决标记-清除算法导致的内存碎片、并发模式失败风险、CPU占用高等问题无法从根本上解决G1收集器的全面超越G1统一收集年轻代和老年代基于Region布局解决了碎片问题支持可预测的停顿时间模型兼顾吞吐量和延迟维护成本过高CMS代码复杂与JVM新特性兼容性差Oracle将开发资源转向G1、ZGC和Shenandoah等新一代收集器六、调优参数类Q11列举5个CMS最常用的调优参数及其作用A-XX:UseConcMarkSweepGC启用CMS收集器-XX:CMSInitiatingOccupancyFraction75老年代使用率达到75%时触发CMS GC默认68%-XX:UseCMSCompactAtFullCollectionFull GC时进行内存压缩JDK8默认开启-XX:CMSFullGCsBeforeCompaction5每5次Full GC后进行一次压缩默认0每次都压缩-XX:ConcGCThreads4设置并发阶段的GC线程数默认是ParallelGCThreads/4CMS vs G1 垃圾收集器 对比面试问答卡片高频考点一、基础定位与核心差异类Q1CMS和G1最根本的区别是什么A内存布局不同CMS采用传统分代式内存布局年轻代老年代连续空间G1采用Region化内存布局将整个堆划分为多个大小相等的独立Region1MB~32MB每个Region可动态扮演Eden、Survivor或老年代设计目标不同CMS唯一目标是最短停顿时间牺牲了部分吞吐量G1目标是在可预测的停顿时间内实现高吞吐量兼顾两者作用范围不同CMS仅收集老年代必须配合年轻代的ParNew/Serial收集器G1同时收集年轻代和老年代是全堆收集器Q2CMS和G1分别在哪个JDK版本成为默认收集器ACMS从未成为过默认收集器JDK 8及之前服务器模式默认是Parallel ScavengeParallel OldG1JDK 9及以后的默认垃圾收集器同时CMS在JDK 9被标记为废弃JDK 14被完全移除二、核心原理对比类Q3CMS和G1使用的核心垃圾回收算法有什么不同ACMS基于标记-清除Mark-Sweep算法优点并发执行停顿时间短缺点产生大量内存碎片G1采用**“整体标记-整理局部复制”** 的混合算法全局看基于标记-整理算法不会产生内存碎片局部看回收Region时采用复制算法将存活对象复制到其他空Region优点彻底解决了内存碎片问题大对象分配更顺畅Q4CMS和G1解决并发标记对象丢失问题的方案有什么不同ACMS采用增量更新Incremental Update算法关注引用的新增当黑色对象新增对白色对象的引用时将黑色对象重新标记为灰色最终标记阶段重新扫描所有灰色对象G1采用原始快照Snapshot At The Beginning, SATB算法关注引用的删除当某个对象的引用被删除时记录下这个引用的原始快照最终标记阶段扫描这些快照确保被删除引用指向的对象不会被误回收性能差异SATB比增量更新效率更高因为它不需要在重新标记阶段重新扫描整个对象图三、回收流程对比类Q5CMS和G1的回收流程有什么本质区别A维度CMSG1回收类型只有老年代CMS GC和Full GC三种回收类型1. Young GC只回收年轻代Region2. Mixed GC回收年轻代部分老年代Region3. Full GC全堆回收应尽量避免核心流程7个阶段4个STW3个并发4个核心阶段2个STW2个并发1. 初始标记STW2. 并发标记并发3. 最终标记STW4. 筛选回收STW并发回收策略每次回收整个老年代采用增量回收策略每次只回收一部分Region根据用户指定的最大停顿时间选择回收价值最高的Region垃圾最多的RegionQ6什么是G1的Mixed GC它和CMS的老年代GC有什么不同AMixed GC定义G1特有的回收模式当老年代占用率达到阈值默认45%时触发同时回收所有年轻代Region和部分老年代Region与CMS老年代GC的区别CMS每次回收整个老年代停顿时间不可控G1每次只回收部分老年代Region停顿时间可预测CMS回收后产生内存碎片G1回收时采用复制算法不会产生碎片CMS只能在老年代满了之后触发G1可以根据停顿时间目标灵活调整回收的Region数量四、性能与问题对比类Q7CMS和G1在停顿时间方面有什么差异ACMS停顿时间不可预测正常情况下停顿时间很短几十毫秒但一旦发生并发模式失败会退化为Serial Old单线程Full GC停顿时间可能长达数秒甚至数十秒G1停顿时间可预测用户可以通过-XX:MaxGCPauseMillis参数指定最大停顿时间默认200msG1会根据历史回收数据计算每个Region的回收耗时选择合适数量的Region进行回收尽量满足停顿时间目标即使发生Full GCJDK 10及以后的G1也支持并行Full GC停顿时间比CMS的Serial Old短得多Q8CMS的并发模式失败和G1的疏散失败有什么区别ACMS并发模式失败原因并发清除阶段产生的浮动垃圾超出了老年代预留空间后果退化为Serial Old单线程收集器全堆Full GC极长STWG1疏散失败Evacuation Failure原因回收Region时没有足够的空Region来存放存活对象后果触发Full GCJDK 10前是单线程JDK 10及以后是多线程并行比CMS的并发模式失败后果轻得多且更容易通过调优避免Q9CMS和G1在处理大对象方面有什么不同ACMS大对象直接分配在老年代问题容易触发提前Full GC且内存碎片会导致大对象分配失败G1专门设计了Humongous Region大对象区大小超过Region一半的对象被视为大对象直接分配在连续的Humongous Region中优点大对象不会进入年轻代避免了频繁复制回收时可以单独回收Humongous Region效率更高五、适用场景与调优对比类Q10CMS和G1分别适用于什么场景ACMS适用场景已不推荐新项目使用JDK 8及以下版本堆内存较小8GB对响应时间要求极高能接受偶尔的长时间停顿CPU资源充足4核及以上G1适用场景推荐所有新项目使用JDK 9及以上版本堆内存较大8GB~64GB需要兼顾吞吐量和响应时间希望有可预测的停顿时间大对象较多的应用Q11CMS和G1最核心的调优参数分别是什么ACMS核心调优参数-XX:CMSInitiatingOccupancyFraction老年代触发GC的阈值-XX:UseCMSCompactAtFullCollectionFull GC时进行内存压缩-XX:ConcGCThreads并发GC线程数G1核心调优参数-XX:MaxGCPauseMillis最大停顿时间目标最重要-XX:G1HeapRegionSize设置每个Region的大小1MB~32MB必须是2的幂-XX:InitiatingHeapOccupancyPercent触发并发标记的堆占用阈值默认45%六、总结对比表面试速记对比维度CMSG1内存布局传统分代连续空间Region化独立小块作用范围仅老年代全堆年轻代老年代核心算法标记-清除标记-整理复制并发标记方案增量更新原始快照SATB停顿时间不可预测有长停顿风险可预测用户可指定内存碎片严重无大对象处理直接分配到老年代Humongous Region专门处理最坏情况退化为Serial Old单线程Full GC并行Full GCJDK10适用堆大小8GB8GB~64GB推荐程度已废弃不推荐新项目推荐所有新项目