对象的软,弱和虚引用
1.介绍
对于大部分对象而言,程序里都会有一个引用变量引用该对象,这是最常见的引用方式。除此以外,java.lang.ref包下提供了三个类:SoftReference,PhantomReference,WeakReference,他们代表着系统对对象的三种引用方式:软引用,虚引用和弱引用
2.强引用(StrongReference)
java程序中最常见的引用方式,程序创建对象,并且把对象赋给引用变量,然后程序根据引用变量来操作实际对象(前面对对象的操作都是基于强引用的方式),当一个对象被一个或者一个以上的引用变量所引用时,它处于可达状态,不可能被系统垃圾回收机制回收
3.软引用(SoftReference)
当一个对象只有软引用时,它有可能被垃圾回收机制回收,对于只有软引用的对象而言,系统空间足够时,它不会被回收,程序也可以使用该对象,当系统空间不足的时候,会被回收(软引用对象一般用在内存敏感的程序中)
4.弱引用(WeakReference)
弱引用和软引用很像,但是弱引用级别更低,对于只有弱引用的对象而言,当系统垃圾回收机制运行时,不管内存是否足够,总会回收该对象占用的内存,但是必须要等到系统垃圾回收机制运行的时候
import java.lang.ref.WeakReference;
public class WeakReferenceDemo {
public static void main(String[]args) throws Exception{
//进行强引用
String str=new String("str_demo");
//进行弱引用
WeakReference wr=new WeakReference(str);
//切断str引用
str=null;
System.out.println(wr.get());
//进行垃圾回收
System.gc();
System.runFinalization();
//取出弱引用
System.out.println(wr.get());
/**
输出结果:
str_demo
null
*/
}
}
上述程序先进行了字符串对象的创建,然后使用str引用变量指向它,然后创建一个wr(弱引用对象)和str引用同一个对象,然后切断str的引用,第一次可以输出wr的对象(使用wr.get()),由于是弱引用,所以在gc后进行对象清理,最后变成null
5.虚引用(PhantomReference)
虚引用完全类似于没有引用,虚引用本身对于对象没有太大的影响,对象甚至感觉不到虚引用,如果一个对象只有虚引用,那么和没有引用的效果大致相同。虚引用是用来跟踪对象被垃圾回收的状态,不能单独使用虚引用,要和引用队列(ReferenceQueue一起使用)
举个栗子:
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class PhantomReferenceTest {
public static void main(String[]args) throws Exception{
Object obj;
//强引用
String str=new String("str");
//创建一个引用队列
ReferenceQueue rq=new ReferenceQueue();
//虚引用,将虚引用到字符串
PhantomReference pr=new PhantomReference(str,rq);
str=null;
//显示弱引用对象
System.out.println(pr.get());
//强制垃圾回收
System.gc();
System.runFinalization();
/**
* 垃圾回收后 会进入引用队列中
* */
System.out.println(rq.poll()==pr);
}
/**
* null true
* */
}
*在gc之后,虚引用的对象会直接进入引用队列中(所以可以跟踪对象)
注:由于垃圾回收的不确定性,如果系统希望从软,弱引用中取出被引用对象时,可能该对象已经被释放了,如果希望使用那个被引用的对象,则必须要重新创建
Object object=new Object();
obj=wr.get();
if(obj==null){
obj=new Object();
wr=new WeakReference(obj);
}else{
//do something
}