引言
作为 Java 程序员,JVM 垃圾回收机制是面试绕不开的高频考点,而'如何判断对象死亡'更是基础中的基础。很多人只记结论却不懂底层逻辑,面试时被面试官追问就慌了阵脚。本文将从原理出发,拆解对象死亡的两种核心判断方式,补充面试高频追问,帮你吃透考点。
一、为什么要判断对象死亡?
在 JVM 中,内存资源是有限的,尤其是堆内存(存储对象实例的核心区域)。如果创建的对象不再被使用,却一直占用内存,久而久之会导致内存泄漏,甚至触发 OOM(OutOfMemoryError)异常,导致程序崩溃。
因此,JVM 垃圾回收的核心前提是:准确判断哪些对象已经'死亡'(不再被任何地方引用,失去使用价值),才能安全地回收其占用的内存,保证程序稳定运行。
简单来说:判断对象死亡,是垃圾回收的'前置操作',也是避免内存浪费的关键。
二、对象死亡判断的两大核心机制
JVM 判断对象死亡,主要依赖两种机制:引用计数法 和 可达性分析算法。其中,可达性分析算法是目前 JVM 主流采用的核心方式,而引用计数法因自身缺陷被淘汰,我们逐一拆解。
2.1 引用计数法(已淘汰)
原理
给每个对象分配一个'引用计数器',当对象被引用一次,计数器值加 1;当引用失效(比如变量赋值为 null),计数器值减 1。当计数器值为 0 时,认为该对象已经死亡,可被回收。
示例(伪代码)
// 创建对象,计数器=1
Object obj = new Object();
// 新增引用,计数器=2
Object obj2 = obj;
// 引用失效,计数器=1
obj = null;
// 引用失效,计数器=0(对象可被回收)
obj2 = null;
致命缺陷:循环引用问题
引用计数法最大的问题是无法解决'循环引用'场景,这也是它被 JVM 淘汰的核心原因。
比如两个对象互相引用,但都不再被其他地方引用,此时它们的计数器值都为 1,无法被回收,导致内存泄漏:
class A {
private B b;
public void setB(B b) { this.b = b; }
}
class B {
private A a;
public void setA(A a) { this.a = a; }
}
();
();
a.setB(b);
b.setA(a);
a = ;
b = ;


