大家好我是程序员二叉。简介本文一次性讲透对象存活判定、GC Roots、三大GC回收算法、分代回收设计逻辑、对象晋升规则、Minor/Major/Full GC区别、STW、主流垃圾收集器、三色标记法等全套核心考点。欢迎点赞收藏关注。一、如何判断对象是否存活引用计数 可达性分析1. 引用计数法实现原理给每个对象分配一个引用计数器对象被引用时计数器1引用失效释放时计数器-1计数器数值为0代表对象可回收。优点实现逻辑简单、判定响应速度快回收时无停顿压力。致命缺陷无法解决对象循环引用场景两个对象互相引用计数器永远无法归零造成内存泄漏因此HotSpot JVM并未采用此方案。2. 可达性分析算法Java虚拟机标准方案实现原理以固定的GC Roots作为起始根节点向下遍历整个引用链路遍历过程中能连通到的对象标记为存活无法抵达的对象判定为垃圾可回收。优点完美规避循环引用问题判定精准稳定是HotSpot、Android ART虚拟机统一使用的存活判断方式。二、GC Roots包含哪些对象作为可达性分析起点、永远不会被回收的根对象一共5大类虚拟机栈栈帧局部变量表中引用的对象方法区中static静态变量引用的对象方法区中运行时常量池引用的常量对象本地方法栈中JNI Native方法引用的对象持有synchronized同步锁的对象三、三大垃圾回收算法及各自优缺点1. 标记-清除Mark-Sweep执行流程先遍历标记所有存活对象 → 统一清理未标记的垃圾对象优点实现简单不需要额外预留内存空间缺点两次全堆扫描整体回收效率偏低清理后产生大量不连续内存碎片大对象分配容易OOM2. 复制算法Copy执行流程把内存划分两块对等区域只使用其中一块GC时将存活对象完整复制到空白区域复制完成直接清空原整块内存优点复制过程无内存碎片、回收速度极快缺点内存利用率天然只有50%存活对象数量多的时候复制开销巨大3. 标记-整理Mark-Compact执行流程第一步标记存活对象第二步将所有存活对象向内存一端紧凑移动最后清空边界以外全部垃圾空间优点无内存碎片、内存利用率100%适合存活率高的内存区域缺点需要移动大量存活对象整体耗时更长、效率偏低四、新生代用复制算法老年代用标记整理的原因新生代适配复制算法新生代对象生命周期极短98%左右的对象Minor GC都会直接消亡存活对象占比极低复制少量存活对象开销很小回收速度快几乎无碎片HotSpot优化采用Eden:From:To8:1:1布局实际内存利用率高达90%规避原生复制算法50%利用率的短板老年代适配标记-整理算法老年代对象存活率极高、生命周期长大量存活对象如果用复制算法拷贝成本极高老年代经常存放大对象一旦产生内存碎片极易分配失败触发Full GC标记整理压缩后空间连续完美适配大对象分配需求五、新生代对象晋升到老年代的四大条件年龄阈值达标默认15对象每熬过一次Minor GC年龄计数器1年龄达到-XX:MaxTenuringThreshold默认值15自动晋升老年代。动态年龄判定Survivor区中相同年龄所有对象占用内存总和 Survivor空间一半大于等于该年龄的全部对象直接晋升无需等到15岁。超大对象直接分配老年代对象大小超过-XX:PretenureSizeThreshold阈值不走新生代直接创建在老年代避免Eden反复复制大数组/大实例。分配担保机制Minor GC后存活对象总量大于Survivor剩余容量无法放入Survivor存活对象直接转移到老年代。六、Minor GC、Major GC、Full GC定义与触发条件1. Minor GC回收范围仅新生代Eden两块Survivor触发条件Eden内存空间填满特点执行频繁、停顿时间短、速度快2. Major GC回收范围仅老年代区域触发条件老年代内存占用接近上限特点速度远慢于Minor GC常伴随一次Minor GC一起发生3. Full GC回收范围整个堆新生代老年代 元空间触发条件手动调用System.gc()老年代空间不足Minor GC担保失败元空间Metaspace内存耗尽特点停顿时间最长、性能损耗最大线上业务要极力减少Full GC频率七、什么是STWStop The World定义垃圾回收执行标记、复制、整理操作时所有Java业务用户线程全部暂停冻结只有GC后台线程允许运行。存在意义保证可达性分析标记阶段对象之间的引用关系不会被业务线程修改防止标记错乱、存活对象误回收。优化方向没有任何收集器能彻底消除STWG1、ZGC、Shenandoah等低延迟收集器的核心目标就是尽可能压缩STW停顿时长。八、主流常用垃圾收集器分类新生代收集器Serial单线程收集器客户端小程序、嵌入式设备使用ParNewSerial多线程优化版曾配合CMS使用Parallel Scavenge主打高吞吐量关注程序整体运行效率老年代收集器Serial OldSerial单线程老年代版本Parallel OldParallel Scavenge配套多线程老年代收集器CMS并发低延迟收集器减少STW时长JDK8经典老年代收集器整堆分代收集器全堆管理G1分区式收集器可预测停顿时间JDK9之后官方默认收集器ZGC超低延迟收集器百微秒级STW大内存堆场景首选ShenandoahRedHat推出的低延迟收集器和ZGC定位一致九、三色标记法原理三色标记是CMS、G1、ZGC等并发GC用来做可达性标记的核心算法用来拆分标记阶段降低STW时长。三种颜色状态白色初始状态尚未扫描访问的对象最终白色对象判定为垃圾灰色已经被扫描到但自身持有的子引用对象还未全部遍历处理完成黑色自身已扫描完毕所有下级引用全部遍历完成标记为稳定存活对象并发标记两大问题浮动垃圾并发过程中新产生的垃圾本次GC无法回收留到下一轮GC处理无安全风险对象漏标致命灰色对象断开黑色引用、同时引用白色对象会导致存活白色对象被误回收解决方案CMS用增量更新、G1/ZGC用原始快照SATB总结面试速记版对象存活HotSpot只用可达性分析放弃引用计数循环引用缺陷GC Roots五大类栈、static、常量、JNI、锁对象三大算法标记清除碎片、复制快、利用率90%新生代、标记整理无碎片适配老年代晋升四条件年龄15、动态年龄、大对象、Survivor存不下GC分级Minor(新生代)、Major(老年代)、Full(全堆尽量规避)STWGC暂停业务线程所有收集器都存在只能缩短不能消除收集器梯队Serial/Parallel/CMS/G1/ZGC延迟逐步提升三色标记白未扫、灰处理中、黑已完成解决漏标保障并发安全
【JVM】垃圾回收GC全套深度详解(大厂高频八股)
发布时间:2026/6/10 17:33:12
大家好我是程序员二叉。简介本文一次性讲透对象存活判定、GC Roots、三大GC回收算法、分代回收设计逻辑、对象晋升规则、Minor/Major/Full GC区别、STW、主流垃圾收集器、三色标记法等全套核心考点。欢迎点赞收藏关注。一、如何判断对象是否存活引用计数 可达性分析1. 引用计数法实现原理给每个对象分配一个引用计数器对象被引用时计数器1引用失效释放时计数器-1计数器数值为0代表对象可回收。优点实现逻辑简单、判定响应速度快回收时无停顿压力。致命缺陷无法解决对象循环引用场景两个对象互相引用计数器永远无法归零造成内存泄漏因此HotSpot JVM并未采用此方案。2. 可达性分析算法Java虚拟机标准方案实现原理以固定的GC Roots作为起始根节点向下遍历整个引用链路遍历过程中能连通到的对象标记为存活无法抵达的对象判定为垃圾可回收。优点完美规避循环引用问题判定精准稳定是HotSpot、Android ART虚拟机统一使用的存活判断方式。二、GC Roots包含哪些对象作为可达性分析起点、永远不会被回收的根对象一共5大类虚拟机栈栈帧局部变量表中引用的对象方法区中static静态变量引用的对象方法区中运行时常量池引用的常量对象本地方法栈中JNI Native方法引用的对象持有synchronized同步锁的对象三、三大垃圾回收算法及各自优缺点1. 标记-清除Mark-Sweep执行流程先遍历标记所有存活对象 → 统一清理未标记的垃圾对象优点实现简单不需要额外预留内存空间缺点两次全堆扫描整体回收效率偏低清理后产生大量不连续内存碎片大对象分配容易OOM2. 复制算法Copy执行流程把内存划分两块对等区域只使用其中一块GC时将存活对象完整复制到空白区域复制完成直接清空原整块内存优点复制过程无内存碎片、回收速度极快缺点内存利用率天然只有50%存活对象数量多的时候复制开销巨大3. 标记-整理Mark-Compact执行流程第一步标记存活对象第二步将所有存活对象向内存一端紧凑移动最后清空边界以外全部垃圾空间优点无内存碎片、内存利用率100%适合存活率高的内存区域缺点需要移动大量存活对象整体耗时更长、效率偏低四、新生代用复制算法老年代用标记整理的原因新生代适配复制算法新生代对象生命周期极短98%左右的对象Minor GC都会直接消亡存活对象占比极低复制少量存活对象开销很小回收速度快几乎无碎片HotSpot优化采用Eden:From:To8:1:1布局实际内存利用率高达90%规避原生复制算法50%利用率的短板老年代适配标记-整理算法老年代对象存活率极高、生命周期长大量存活对象如果用复制算法拷贝成本极高老年代经常存放大对象一旦产生内存碎片极易分配失败触发Full GC标记整理压缩后空间连续完美适配大对象分配需求五、新生代对象晋升到老年代的四大条件年龄阈值达标默认15对象每熬过一次Minor GC年龄计数器1年龄达到-XX:MaxTenuringThreshold默认值15自动晋升老年代。动态年龄判定Survivor区中相同年龄所有对象占用内存总和 Survivor空间一半大于等于该年龄的全部对象直接晋升无需等到15岁。超大对象直接分配老年代对象大小超过-XX:PretenureSizeThreshold阈值不走新生代直接创建在老年代避免Eden反复复制大数组/大实例。分配担保机制Minor GC后存活对象总量大于Survivor剩余容量无法放入Survivor存活对象直接转移到老年代。六、Minor GC、Major GC、Full GC定义与触发条件1. Minor GC回收范围仅新生代Eden两块Survivor触发条件Eden内存空间填满特点执行频繁、停顿时间短、速度快2. Major GC回收范围仅老年代区域触发条件老年代内存占用接近上限特点速度远慢于Minor GC常伴随一次Minor GC一起发生3. Full GC回收范围整个堆新生代老年代 元空间触发条件手动调用System.gc()老年代空间不足Minor GC担保失败元空间Metaspace内存耗尽特点停顿时间最长、性能损耗最大线上业务要极力减少Full GC频率七、什么是STWStop The World定义垃圾回收执行标记、复制、整理操作时所有Java业务用户线程全部暂停冻结只有GC后台线程允许运行。存在意义保证可达性分析标记阶段对象之间的引用关系不会被业务线程修改防止标记错乱、存活对象误回收。优化方向没有任何收集器能彻底消除STWG1、ZGC、Shenandoah等低延迟收集器的核心目标就是尽可能压缩STW停顿时长。八、主流常用垃圾收集器分类新生代收集器Serial单线程收集器客户端小程序、嵌入式设备使用ParNewSerial多线程优化版曾配合CMS使用Parallel Scavenge主打高吞吐量关注程序整体运行效率老年代收集器Serial OldSerial单线程老年代版本Parallel OldParallel Scavenge配套多线程老年代收集器CMS并发低延迟收集器减少STW时长JDK8经典老年代收集器整堆分代收集器全堆管理G1分区式收集器可预测停顿时间JDK9之后官方默认收集器ZGC超低延迟收集器百微秒级STW大内存堆场景首选ShenandoahRedHat推出的低延迟收集器和ZGC定位一致九、三色标记法原理三色标记是CMS、G1、ZGC等并发GC用来做可达性标记的核心算法用来拆分标记阶段降低STW时长。三种颜色状态白色初始状态尚未扫描访问的对象最终白色对象判定为垃圾灰色已经被扫描到但自身持有的子引用对象还未全部遍历处理完成黑色自身已扫描完毕所有下级引用全部遍历完成标记为稳定存活对象并发标记两大问题浮动垃圾并发过程中新产生的垃圾本次GC无法回收留到下一轮GC处理无安全风险对象漏标致命灰色对象断开黑色引用、同时引用白色对象会导致存活白色对象被误回收解决方案CMS用增量更新、G1/ZGC用原始快照SATB总结面试速记版对象存活HotSpot只用可达性分析放弃引用计数循环引用缺陷GC Roots五大类栈、static、常量、JNI、锁对象三大算法标记清除碎片、复制快、利用率90%新生代、标记整理无碎片适配老年代晋升四条件年龄15、动态年龄、大对象、Survivor存不下GC分级Minor(新生代)、Major(老年代)、Full(全堆尽量规避)STWGC暂停业务线程所有收集器都存在只能缩短不能消除收集器梯队Serial/Parallel/CMS/G1/ZGC延迟逐步提升三色标记白未扫、灰处理中、黑已完成解决漏标保障并发安全