摘抄自:《Android 进阶解密》
在 JDK1.2 之后引入的。
1、强引用
直接新建一个对象 (new) 并赋值给引用变量,该对象就被持有强引用。
一个对象具有强引用是不就被回收的,即使内存不足时或进一步抛出 OutOfMemory 异常时。
2、软引用
一个对象只具有软引用,在内存不够时会被回收。使用 SoftReference
实现。
3、弱引用
一个对象只具有弱引用,则下一次垃圾回收时会被回收。使用 WeakReference
实现。
// 生成一个 Object 实例对象,假设它为 X。
// 注意 obj 只是引用变量,指向 X,并不是 X 本身
Object obj = new Object();
// 生成一个 WeakReference 实例对象,并赋值给 weakReference
WeakReference<Object> weakReference = new WeakReference<>(obj);
// 去除强引用,之后就只有 weakReference 持有 X 的引用了,且为弱引用
obj = null;
// 触发 GC,X 就会被回收了。
// 注意,是 X 对象被回收,此时 weakReference 该引用变量指向的 WeakReference 实例还有没有被回收
Runtime.getRuntime().gc();
4、虚引用
虚引用不会决定对象的生命周期,对象只存在虚引用时,与没有任何引用一样,随时都会被回收。
只不过具有虚引用的对象在回收时,会收到一个系统通知,这是其主要作用。
使用 PhantomReference
实现。
ReferenceQueue
通常我们将其 ReferenceQueue 翻译为引用队列,换言之就是存放引用的队列,保存的是 Reference 对象。其作用在于 Reference 对象所引用的对象被 GC 回收时,该 Reference 对象将会被加入引用队列中(ReferenceQueue)的队列末尾。
ReferenceQueue referenceQueue = new ReferenceQueue();
// 生成一个 Object 实例对象,假设它为 X
Object object = new Object();
Reference ref = null;
// 生成 WeakReference 对象实例,假设为 Y,并设置引用队列
WeakReference<Object> weakReference = new WeakReference<>(object, referenceQueue);
System.out.println("=====================");
while ((ref = referenceQueue.poll()) != null) {
System.out.println(ref.toString());
System.out.println(ref.get());
}
System.out.println();
object = null;
Runtime.getRuntime().gc();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("=====================");
while ((ref = referenceQueue.poll()) != null) {
System.out.println(ref.toString());
System.out.println(ref.get());
}
打印结果:
=====================
=====================
java.lang.ref.WeakReference@45ee12a7
null
根据打印结果,可以看到,X 已经被回收了,Y 被放入到引用队列中(更准确的说,应该是引用队列中的一个节点持有了 Y 的引用。)