引用链路径分析是jvm可达性分析算法的核心,从gc roots出发沿强引用等有效引用逐级访问,路径完整的对象被视为存活;gc roots包括虚拟机栈、方法区静态/常量引用、本地方法栈jni引用、synchronized锁对象及jvm内部关键对象。

引用链路径分析是 JVM 垃圾回收中可达性分析算法的核心环节,它决定一个对象是否“还活着”。简单说:只要从 GC Roots 出发,能沿着引用关系一路走到某个对象,这个对象就不可回收;反之,若所有路径都断开,它就被判定为垃圾。
什么是引用链?
引用链指从 GC Roots 开始,通过强引用(或部分软/弱引用,在特定阶段)逐级向下访问形成的对象连接路径。例如:
GC Roots → 局部变量 obj → obj.fieldA → fieldA.child → child.data
只要这条链完整,data 对象就处于“可达”状态,不会被回收。
GC Roots 包含哪些起点?
这些起点是 JVM 认为“绝对存活”的对象,作为引用链的源头:
- 虚拟机栈(包括每个线程的栈帧)中引用的对象(如方法参数、局部变量)
- 方法区中类的静态属性引用的对象(public static final Map CACHE = new HashMap() 中的 map 实例)
- 方法区中常量池引用的对象(如字符串字面量 "hello" 在字符串常量池中的实例)
- 本地方法栈中 JNI(Java Native Interface)引用的对象
- 被 synchronized 锁住的对象(monitor 持有者)
- JVM 内部关键对象,如基本类型对应的 Class 实例、系统类加载器等
引用类型如何影响路径有效性?
不是所有引用都能构成有效引用链——是否“算数”,取决于引用类型和 GC 阶段:
- 强引用:默认赋值方式(Object o = new Object()),始终参与引用链判断,只要链不断,对象一定不回收
- 软引用:仅在内存不足时才被 GC 断链,平时仍算有效路径;适合缓存场景
-
弱引用:不构成“存活保障”,GC 时直接清空引用,对应路径立即失效(WeakReference
wr = new WeakReference(s) ) - 虚引用:完全不参与可达性判断,仅用于回收通知,对引用链无贡献
常见误判场景与注意点
实际分析中容易忽略的细节:
- 循环引用本身不阻断回收:A 引用 B、B 引用 A,但两者都不被 GC Roots 直接或间接引用 → 整个闭环会被一并回收(区别于 Python 的引用计数)
- 静态集合持有对象需谨慎:static List
users = new ArrayList() 中的 User 实例,因被 static 字段引用,会一直延长生命周期,易导致内存泄漏 - ThreadLocal 可能隐式延长引用:若未调用 remove(),其内部 map 中的 value 即使业务逻辑已结束,仍可能被当前线程的 ThreadLocalMap 引用而无法回收
- finalize() 方法不保证执行时机,且仅触发一次,不能依赖它重建引用链











