概念介绍
1 Reference
描述一个对象的引用。其内部维持一个queue引用,用于跟踪对象的回收情况,当对象被回收时将当前reference引用入队
2 SoftReference
软引用,仅当JVM内存紧张时会回收关联对象,即JVM在抛出OOM异常之前会回收所有的SoftReference关联的对象。
在对象被回收之后的某个时间点(立即或延迟)进行入队操作
3 WeakReference
弱引用,当JVM执行垃圾回收时(如System.gc触发)回收其关联对象。
4 PhantomReference
虚引用,实现了延迟可控、可再生(重复使用对象)的回收机制。
当JVM第一次垃圾回收时并不回收关联对象,而是直接将refercence对象入队;
当reference对象操作出队(poll)时,其内部Queue对象被置换为一个特殊的NULL队列(不允许入队);
于是当JVM第二次垃圾回收时尝试将其入队发现失败,于是JVM才将关联对象回收。
为了保护虚引用对象可再生,该reference的get方法总是返回null。
代码示例
package reference;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
public class ReferenceTest {
public static void main(String[] args) {
System.out.println("弱引用==============");
testWeakReference();
System.out.println("软引用==============");
testSoftReference();
System.out.println("虚引用==============");
testPhantomReference();
}
/**
* 测试弱引用
*/
private static void testWeakReference() {
Object obj = new Object();
// 构建弱引用
ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
WeakReference<Object> weakRef = new WeakReference<Object>(obj, refQueue);
// 关联对象
System.out.println(weakRef.get());
// 检查入队情况
System.out.println(refQueue.poll());
obj = null;
System.gc();
// 延迟,等待入队操作执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 关联对象是否回收
System.out.println(weakRef.get());
// 是否入队
System.out.println(refQueue.poll());
}
/**
* 测试软引用
*/
private static void testSoftReference() {
Object obj = new Object();
ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
SoftReference<Object> weakRef = new SoftReference<Object>(obj, refQueue);
// 关联对象
System.out.println(weakRef.get());
// 检查入队情况
System.out.println(refQueue.poll());
obj = null;
System.gc();
// 延迟,等待入队操作执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 关联对象是否回收
System.out.println(weakRef.get());
// 是否入队
System.out.println(refQueue.poll());
}
/**
* 测试虚引用
*/
private static void testPhantomReference() {
Object obj = new Object();
ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
PhantomReference<Object> weakRef = new PhantomReference<Object>(obj, refQueue);
// 关联对象
System.out.println(weakRef.get());
// 检查入队情况
System.out.println(refQueue.poll());
obj = null;
System.gc();
// 延迟,等待入队操作执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 关联对象是否回收
System.out.println(weakRef.get());
// 是否入队
System.out.println(refQueue.poll());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Phantom Reference's referent recycled.");
}
}
输出
弱引用==============
java.lang.Object@1fb8ee3
null
null
java.lang.ref.WeakReference@14318bb
软引用==============
java.lang.Object@ca0b6
null
java.lang.Object@ca0b6
null
虚引用==============
null
null
null
java.lang.ref.PhantomReference@1b67f74
Phantom Reference's referent recycled.
相关博文
http://blog.sina.com.cn/s/blog_667ac0360102e9f3.html作者:
zale出处:
http://www.cnblogs.com/littleatp/, 如果喜欢我的文章,请
关注我的公众号本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
原文链接如有问题, 可留言咨询.