可达性分析是HotSpot判定对象存活的唯一标准,以GC Roots(栈帧局部变量、静态属性、常量、JNI引用)为起点遍历引用链,不可达对象即为垃圾。

掌握 JVM 垃圾回收(GC)不是背概念,而是理清“谁是垃圾→在哪回收→怎么回收→为何这样设计”这条主线。重点不在记住所有参数,而在理解每一步背后的权衡逻辑。
紧扣对象存活判定这个起点
所有 GC 行为都始于判断“这个对象还能不能用”。必须吃透可达性分析算法——它才是 HotSpot 实际采用的唯一标准。
- GC Roots 不是抽象概念,要能随手写出四类典型:栈帧里的局部变量、类的静态字段、方法区的常量、本地方法(JNI)引用的对象
- 注意“不可达≠立刻死亡”:第一次标记后,若对象重写了 finalize() 且未执行过,会进 F-Queue 队列,还有一次“复活”机会(但不推荐依赖)
- 引用计数法只需了解其循环引用缺陷即可,HotSpot 从未使用,面试中点到为止
分代回收结构是理解 GC 类型的关键
堆被划分为新生代(Eden + 2 Survivor)和老年代,不是为了好看,而是因为对象生命周期差异极大。
- 新生代对象“朝生夕死”,所以用复制算法:只复制存活对象,天然无碎片,效率高;8:1:1 的 Eden/Survivor 比例就是为提升内存利用率做的优化
- 老年代对象“长期存活”,复制成本太高,改用标记-整理(避免碎片)或标记-清除(CMS 曾用,但碎片风险大)
- Minor GC → Major GC → Full GC 的区别,本质是回收范围不同:前者只动新生代,后者涉及整个堆+方法区,停顿时间逐级拉长
四种引用类型决定回收时机弹性
强、软、弱、虚引用不是语法糖,而是 JVM 给开发者留出的回收控制接口。
- 强引用:Object obj = new Object() —— 只要它在,对象就不会被回收
- 软引用:SoftReference —— 内存快撑不住(OOM 前)才回收,适合做缓存(如图片缓存)
- 弱引用:WeakReference —— 下次 GC 必收,适合临时映射(如 ThreadLocal 的 key)
- 虚引用:PhantomReference —— 无法通过它访问对象,仅用于在对象被回收时收到通知(配合 ReferenceQueue)
把算法对比落到具体场景里记
别孤立记“标记-清除缺点是碎片”,要想:为什么 CMS 用它?因为它并发清理,停顿短,适合对响应敏感系统;又为什么 ZGC/G1 要避免它?因为它们靠内存规整来支持并发移动。
- 标记-清除:简单直接,适合老年代低频回收,但碎片导致大对象分配失败
- 复制算法:高效无碎片,但浪费空间,只适合存活率低的区域(新生代)
- 标记-整理:解决碎片问题,但移动对象要更新所有引用,STW 时间更长


















