7、强引用 、软引用、 弱引用、虚引用
/**
* 7、强引用 、软引用、 弱引用、虚引用
*/
@Test
public void test007() {
//强引用
test007_1();
//软引用
test007_2();
//弱引用
test007_3();
//虚引用
test007_4();
}
1.强引用
public void test007_1() {
/**
* 只要引用存在,垃圾回收器永远不会回收
*/
Object obj = new Object();
}
2.软引用
public void test007_2() {
/**
* 非必须引用,内存溢出之前进行回收,可以通过以下代码实现
* 这时候sf是对obj的一个软引用,通过sf.get()方法可以取到这个对象,当然,当这个对象被标记为需要回收的对象时,则返回null;
* 软引用主要用于实现类似缓存的功能,在内存足够的情况下直接通过软引用取值,无需从繁忙的真实来源查询数据,提升速度;当内存不足时,
* 自动删除这部分缓存数据,从真正的来源查询这些数据。
*/
Object obj = new Object();
SoftReference
3.弱引用
public void test007_3() {
/**
* 1、ThreadLocal中,获取到线程私有对象是通过线程持有的一个threadLocalMap,然后传入ThreadLocal当做key获取到对象的,这时候就有个问题,
* 如果你在使用完ThreadLocal之后,将其置为null,这时候这个对象并不能被回收,因为他还有 ThreadLocalMap->entry->key的引用,直到该线程
* 被销毁,但是这个线程很可能会被放到线程池中不会被销毁,这就产生了内存泄露,jdk是通过弱引用来解决的这个问题的,entry中对key的引用是弱引用,
* 当你取消了ThreadLocal的强引用之后,他就只剩下一个弱引用了,所以也会被回收。
* 2、弱引用是在第二次垃圾回收时回收,短时间内通过弱引用取对应的数据,可以取到,当执行过第二次垃圾回收时,将返回null。
*/
Object obj = new Object();
WeakReference wf = new WeakReference(obj);
obj = null;
wf.get();//有时候会返回null
}
4.虚引用
public void test007_4() {
/**
* “虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
* 虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。
* ReferenceQueue queue = new ReferenceQueue ();
* PhantomReference pr = new PhantomReference (object, queue);
* 程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
*/
Object obj = new Object();
PhantomReference pf = new PhantomReference(obj);
obj = null;
pf.get();//永远返回null
}