在 Java 中,引用类型决定了对象与垃圾回收器(GC)之间的交互方式。Java 提供了四种引用类型:强引用、软引用、弱引用和虚引用。它们的主要区别在于垃圾回收器对待这些引用的方式不同。
1. 强引用(Strong Reference)
强引用是 Java 中最常见的引用类型。如果一个对象具有强引用,垃圾回收器永远不会回收该对象,即使内存不足时也不会回收。
特点:
- 只要强引用存在,对象就不会被回收。
- 如果对象不再需要,需要显式地将引用设置为
null
,以便垃圾回收器回收。
示例:
Object obj = new Object(); // 强引用
obj = null; // 显式解除强引用,对象可以被回收
2. 软引用(Soft Reference)
软引用用于描述一些还有用但非必需的对象。只有在内存不足时,垃圾回收器才会回收软引用指向的对象。
特点:
- 适合用于实现内存敏感的缓存。
- 在内存不足时,垃圾回收器会回收软引用对象。
- 可以通过
SoftReference
类创建软引用。
示例:
SoftReference<Object> softRef = new SoftReference<>(new Object());
Object obj = softRef.get(); // 获取软引用对象
if (obj == null) {
// 对象已被回收
}
3. 弱引用(Weak Reference)
弱引用比软引用更弱一些。如果一个对象只有弱引用,垃圾回收器在下一次运行时就会回收该对象,无论内存是否充足。
特点:
- 适合用于实现缓存或临时映射表(如
WeakHashMap
)。 - 垃圾回收器会立即回收弱引用对象。
- 可以通过
WeakReference
类创建弱引用。
示例:
WeakReference<Object> weakRef = new WeakReference<>(new Object());
Object obj = weakRef.get(); // 获取弱引用对象
if (obj == null) {
// 对象已被回收
}
4. 虚引用(Phantom Reference)
虚引用是最弱的一种引用类型。如果一个对象只有虚引用,垃圾回收器会随时回收该对象。虚引用的主要作用是跟踪对象被垃圾回收的状态。
特点:
- 虚引用必须与引用队列(
ReferenceQueue
)一起使用。 - 无法通过虚引用获取对象(
get()
方法总是返回null
)。 - 适合用于管理堆外内存(如 NIO 的 DirectBuffer)或实现资源清理机制。
示例:
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), queue);
Object obj = phantomRef.get(); // 总是返回 null
// 当对象被回收时,虚引用会被加入到引用队列中
引用类型对比
引用类型 | 回收时机 | 用途 | 实现类 |
---|---|---|---|
强引用 | 永远不会回收 | 普通对象引用 | 直接赋值 |
软引用 | 内存不足时回收 | 缓存 | SoftReference |
弱引用 | 垃圾回收时立即回收 | 缓存、临时映射表 | WeakReference |
虚引用 | 垃圾回收时随时回收 | 跟踪对象回收状态、资源清理 | PhantomReference |
引用队列(ReferenceQueue)
软引用、弱引用和虚引用都可以与引用队列(ReferenceQueue
)一起使用。当引用对象被垃圾回收器回收时,引用本身会被加入到引用队列中,程序可以通过轮询引用队列来执行一些清理操作。
示例:
ReferenceQueue<Object> queue = new ReferenceQueue<>();
WeakReference<Object> weakRef = new WeakReference<>(new Object(), queue);
// 监控引用队列
Reference<?> ref = queue.poll();
if (ref != null) {
// 引用对象已被回收
}
总结
- 强引用:最常见的引用类型,对象不会被回收。
- 软引用:适合缓存,内存不足时回收。
- 弱引用:适合临时缓存,垃圾回收时立即回收。
- 虚引用:用于跟踪对象回收状态和资源清理。
理解这些引用类型有助于更好地管理内存和优化 Java 应用程序的性能。
THE END
暂无评论内容