JAVA八股文第三章(JVM 中如何判断对象可以被回收)
JVM 中如何判断对象可以被回收可达性分析彻底讲清在 Java 中我们不需要手动释放内存因为 JVM 会通过GC垃圾回收机制自动回收对象。但一个核心问题是JVM 是如何判断一个对象“可以被回收”的这篇文章将从原理到实现彻底讲清这个问题。一、核心结论一句话版一个对象如果“无法从 GC Roots 访问到”就可以被回收二、两种判断方式历史 现状在理论上有两种判断对象是否存活的方法1️⃣ 引用计数法Reference Counting❌原理每个对象有一个引用计数器 被引用 → 1 引用失效 → -1 计数为 0 → 可回收❗ 问题无法解决“循环引用”示例AanewA();BbnewB();a.bb;b.aa; 结果a 和 b 互相引用计数都不为 0但实际上已经“没用了”结论Java 不使用引用计数法2️⃣ 可达性分析Reachability Analysis✅ JVM 实际使用的方法三、什么是可达性分析 核心思想从一组“根对象GC Roots”出发 看对象是否能被访问到✔ 判断规则能访问到 → 存活访问不到 → 可回收四、什么是 GC Roots GC Roots 是一组“永远不会被回收的起点对象”常见 GC Roots1. 虚拟机栈中的局部变量引用 2. 方法区中的静态变量 3. 方法区中的常量 4. 本地方法栈中的引用 简单理解GC Roots 所有“正在使用的入口”五、判断过程图解思维假设内存中有这样一个结构GC Roots → A → B → C D → E没有任何引用指向分析A、B、C可以从 GC Roots 访问 → 存活D、E不可达 → 可回收 本质只要断开与 GC Roots 的连接就会被回收六、再深入对象一定会被立即回收吗 不一定对象回收需要两次判断✔ 第一次是否可达是否有引用✔ 第二次是否需要执行 finalize()finalize 机制Overrideprotectedvoidfinalize()throwsThrowable{// 对象“自救”} 特点对象在 finalize 中可以“复活”只会执行一次不推荐使用已逐步废弃 结论即使不可达也不一定立即回收七、引用类型高级面试点Java 中不仅有“强引用”还有 4 种引用类型1️⃣ 强引用Strong ReferenceObjectobjnewObject(); 特点只要有强引用就不会被回收2️⃣ 软引用Soft Reference 内存不足时才回收3️⃣ 弱引用Weak Reference 只要发生 GC 就会被回收4️⃣ 虚引用Phantom Reference 用于跟踪对象回收几乎不用八、完整判断流程总结版1. 从 GC Roots 出发进行可达性分析 2. 判断对象是否可达 3. 若不可达 → 标记为“可回收” 4. 判断是否需要执行 finalize 5. 若未“复活” → 最终回收九、面试高频问题总结✔ JVM 如何判断对象是否可以被回收 可达性分析算法✔ 为什么不用引用计数法 无法解决循环引用问题✔ 什么是 GC Roots 一组作为起点的对象栈、静态变量等✔ 对象一定会被立即回收吗 不一定finalize 机制✔ 强引用会被回收吗 不会只要存在十、终极总结判断对象是否回收的本质 看它是否“还能被用到”更技术一点是否能从 GC Roots 可达十一、结语理解“对象如何被回收”是掌握 JVM 的关键一步想学 GC → 必须懂可达性分析想优化内存 → 必须懂引用类型想应对面试 → 这是必考题如果你能把本文吃透JVM 内存机制已经迈入进阶阶段。