WeakReference简介

2019-05-09  本文已影响0人  overflow_e4e4

WeakReference简介

什么是引用

首先要把引用和对象区别开来,比如Car car = new Car();这条语句新建了一个对象new Car(),同时把car这个引用指向了这个new Car()对象。java在gc的时候, 如果发现没有任何引用指向某对象, 该对象就会被回收。比如:Car car = null;

弱引用

上述描写的是java中的强引用,本文还将介绍一种WeakReference弱引用。当GC时,如果一个对象只有弱引用指向他时候,那个对象就会被回收。
代码:

package reference;

import invoke.Car;

import java.lang.ref.WeakReference;

public class WeakReferenceDemo {
    public static void main(String[] args) {

        WeakReference<Car> weakReference = new WeakReference<>(new Car());
        System.out.println(weakReference.get());
        System.gc();
        System.out.println(weakReference.get());

    }
}

输出结果:

invoke.Car@198e2867
null

可以看到在gc之后新建的new Car()对象因为只有弱引用指向他而被回收了。因为实际java程序中GC时机的不确定性,所以WeakReference常用作为cache,适合一些耗内存且更迭快速的对象。

ReferenceQueue的使用

WeakReference还提供了一种构造函数:

public WeakReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
    }

可以再传入一个ReferenceQueue作为第二个参数。
所以我把之前的程序稍加修改了一番:

package reference;

import invoke.Car;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

public class WeakReferenceDemo {
    public static void main(String[] args) {

        ReferenceQueue<Car> referenceQueue = new ReferenceQueue<>();
        WeakReference<Car> weakReference = new WeakReference<>(new Car(), referenceQueue);
        System.out.println(weakReference.get());
        System.gc();
        System.out.println(weakReference.get());

    }
}

这个ReferenceQueue的主要作用是存放那些已经被gc的reference。
通过debug时候的两张截图能清晰看到gc前后的变化:


截图1.png
截图2.png

referenceQueue存入了被gc的对象的弱引用。

SoftReference和PhantomReference

java中共有4种引用,上文已经讲了2种(强引用和弱引用),还有SoftReference和PhantomReference。
SoftReference和WeakReference类似,但他回收对象的条件要再加一条,当内存不足够的时候。
PhantomReference的情况就比较复杂了PhantomReference必须要和ReferenceQueue联合使用,虚引用并不会影响对象的生命周期。
当GC一旦发现了虚引用对象,则会将PhantomReference对象插入ReferenceQueue队列,作为跟踪垃圾回收器收集对象这一活动的情况。

上一篇 下一篇

猜你喜欢

热点阅读