java 垃圾回收中并不使用引用计数法,而是采用可达性分析算法(reachability analysis)来判定对象是否存活。引用计数法是一种通过给对象添加计数器,在引用关系变化时增减计数的机制,但因为它无法解决循环引用问题且增加运行时开销,所以被 java 虚拟机弃用。

为什么 Java 不选择引用计数法?
Java 放弃引用计数法的核心原因在于它无法正确处理循环引用,以及每次对象操作都需要更新计数的性能损耗。在引用计数算法中,如果两个对象相互引用但不再被任何 GC Roots 引用,它们的引用计数都不为零,导致垃圾收集器认为它们仍然存活,从而产生内存泄漏。此外,维护计数器的原子性需要额外的同步开销,这会降低程序运行效率。

public class ReferenceCountingGC {
public Object instance = null;
public static void main(String[] args) {
// 创建两个对象,它们互相引用
ReferenceCountingGC objA = new ReferenceCountingGC();
ReferenceCountingGC objB = new ReferenceCountingGC();
objA.instance = objB;
objB.instance = objA;
// 将外部引用置空
objA = null;
objB = null;
// 触发垃圾回收
System.gc();
}
}
上述代码展示了典型的循环引用场景。objA 和 objB 互相持有对方的引用。当我们将 objA 和 objB 置为 null 后,从 GC Roots 出发已经无法到达这两个对象。如果使用引用计数法,由于它们互相引用,计数不为零,不会被回收。而 Java 的可达性分析能正确识别它们为不可达对象并回收内存。
立即学习“Java免费学习笔记(深入)”;
掌握 ES6+ 特性,包括 async/await、解构、扩展运算符、箭头函数、Promise、模块、迭代器、生成器以及函数式编程模式,编写简洁高效的 Java
Java 实际使用的可达性分析算法是什么?
Java 虚拟机使用可达性分析算法(Reachability Analysis),通过一系列称为 "GC Roots" 的对象作为起点,向下搜索引用链。如果某个对象到 GC Roots 没有任何引用链相连,则证明该对象是不可用的,可以被回收。主要的 GC Roots 包括虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象等。

import java.lang.ref.WeakReference;
public class ReachabilityAnalysisDemo {
public static void main(String[] args) {
// 创建一个强引用对象
byte[] buffer = new byte[1024 * 1024]; // 1MB
// 创建一个弱引用指向该对象
WeakReference<byte[]> weakRef = new WeakReference<>(buffer);
// 断开强引用
buffer = null;
// 尝试获取弱引用对象
System.out.println("Weak reference is alive: " + (weakRef.get() != null));
// 强制垃圾回收
System.gc();
// 再次检查弱引用
System.out.println("After GC, weak reference is alive: " + (weakRef.get() != null));
}
}
这个示例演示了不同引用类型在可达性分析中的表现。虽然 buffer 被置为 null,但由于存在弱引用 weakRef,对象在第一次检查时可能仍存活。但在调用 System.gc() 后,由于没有强引用指向该对象,垃圾收集器会将其回收,此时 weakRef.get() 返回 null。这体现了 Java 基于引用链状态的回收机制,而非简单的计数。
不同引用类型对垃圾回收的影响
Java 提供了四种引用类型:强引用、软引用、弱引用和虚引用,它们在可达性分析中具有不同的行为。强引用是最常见的引用,只要强引用存在,对象就不会被回收。软引用在内存不足时会被回收,常用于缓存。弱引用在垃圾回收时总是被回收,用于实现更灵敏的对象生命周期管理。虚引用则主要用于跟踪对象被垃圾回收的状态。
在实际开发中,理解这些引用类型有助于优化内存使用。例如,使用弱引用可以避免内存泄漏,特别是在处理大型对象或监听器时。软引用适合实现内存敏感的缓存策略。通过合理选择引用类型,开发者可以在内存使用和对象生命周期之间取得平衡。

















