java垃圾回收通过可达性分析算法判定对象存活,以gc roots(如虚拟机栈局部变量、静态字段、常量池引用、jni引用)为起点沿强引用链遍历,不可达对象被标记为可回收,天然解决循环引用问题。

Java 垃圾回收(GC)并不直接“回收无引用的对象”,而是通过可达性分析判定对象是否存活,再回收那些被判定为“不可达”的对象——也就是从 GC Roots 出发无法通过引用链访问到的对象。
什么是 GC Roots?
GC Roots 是一组必须被视为活跃的引用起点,包括:
- 虚拟机栈(栈帧中的局部变量表)中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象(如字符串常量池里的 String)
- 本地方法栈中 JNI(即 Native 方法)引用的对象
如何判断一个对象“无引用”?
Java 使用可达性分析算法,而非早期 Java(1.2 之前)用的引用计数法。具体过程是:
- 从所有 GC Roots 出发,沿着每条引用链向下搜索
- 能被遍历到的对象标记为“可达”(即存活)
- 未被标记的对象,就是“不可达”的,即逻辑上“无有效引用”,可被回收
注意:即使对象重写了 finalize() 方法,也只可能被“复活”一次(在 F-Queue 队列中执行后若重新与 GC Roots 建立引用),但该机制已自 Java 9 起被弃用,不建议依赖。
回收发生在什么时候?
GC 不是实时的,而是在满足一定条件时由 JVM 自动触发,例如:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 堆内存不足(如 Eden 区满)时触发 Minor GC
- 老年代空间不足或 Minor GC 后晋升失败时可能触发 Full GC
- 系统空闲或显式调用
System.gc()(仅建议,不保证立即执行)
不同垃圾收集器(如 G1、ZGC、Shenandoah)实现细节不同,但核心判断依据始终是可达性分析结果。
常见误解澄清
“对象 = null” 并不等于立刻被回收:这只是断开了局部变量对它的引用;真正回收时机取决于下一次 GC 是否将它判定为不可达。
循环引用不会阻止回收:A 引用 B,B 引用 A,但二者都不被 GC Roots 连接 → 两者都会被回收(引用计数法才无法处理这种情况)。
弱引用(WeakReference)、软引用(SoftReference)、虚引用(PhantomReference)会影响回收时机,但它们本身不改变“可达性分析”的判定逻辑,只是在不同阶段提供干预机会。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










