在Java中,对象的引用被分为四种类型,根据它们的生命周期和垃圾回收的行为来区分:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。下面是这四种引用的简要说明和代码示例:
1. 强引用(Strong Reference)
强引用是最常见的引用类型。如果一个对象具有强引用,那么垃圾回收器就永远不会回收它,即使内存不足导致OutOfMemoryError之前,垃圾回收器也不会去回收具有强引用的对象。
示例:
Object strongRef = new Object(); // 强引用
2. 软引用(Soft Reference)
软引用是用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。
示例:
SoftReference<Object> softRef = new SoftReference<>(new Object()); // 软引用
Object softObject = softRef.get(); // 获取软引用指向的对象
3. 弱引用(Weak Reference)
弱引用也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收只被弱引用关联的对象。
示例:
WeakReference<Object> weakRef = new WeakReference<>(new Object()); // 弱引用
Object weakObject = weakRef.get(); // 获取弱引用指向的对象,可能在垃圾收集后返回null
4. 虚引用(Phantom Reference)
下滑查看解决方法
虚引用也称为幽灵引用或幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
示例(需要配合ReferenceQueue
使用):
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), queue);
// 虚引用在创建时必须提供一个与之关联的队列
// 当垃圾回收器准备回收该对象(即对象可回收)时,会先把这个虚引用加入到与之关联的队列中
// 程序可以通过检查与该虚引用关联的队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收
// 如果程序发现某个虚引用已经被加入到队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动
需要注意的是,虚引用必须和ReferenceQueue
联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的队列中。程序可以通过检查与虚引用关联的队列中是否已经加入了虚引用来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。