Java四种引用类型(强引用,软引用,弱引用,虚引用)

     强引用不能很好描述一些“食之无味,弃之可惜”的对象。毕竟当对象释放掉后再想找回就不可能了。所以当内存空间还充足时,则尽量保留在内存中;如果内存空间在进行垃圾收集后还是非常紧张,则可以抛弃这些对象。很多系统的缓存功能符合这样的应用场景。

1 强引用

我们平时所使用的引用就是强引用。
也就是通过关键字new创建的对象所关联的引用就是强引用。
只要强引用存在,该对象永远也不会被回收。
A a = new A();
B b = newB(a);
a =null;  //此时对象b还依赖于对象a,所以对象a还是不能被回收。当对象b不再需要使用对象a时,a对象不能及时被释放。


2 软引用

只有当JVM内存不足时,垃圾回收器会释放那些只被软引用指向的对象。若全部释放这些对象后内存还不足,才会抛出OOM异常。
软引用通过SoftReference类实现。
软引用的生命周期比强引用短一些。
适合于创建缓存:如一个图像编辑器的程序。打开多张图片,如果使用软引用来指向图像缓存文件,垃圾回收器便会在内存不足时回收掉这些内存。

3 弱引用 

        一般来说,引用变量会随着其方法的栈帧popup出来。GC随后释放掉之前引用指向的内存。这也是垃圾收集器的设计理念。但是,当程序创建的引用越来越多,GC无法回收的对象也越来越多。而在引用没有失效之前,GC是无法判断哪些是可以回收,哪些还不能回收的,因为它们都有强引用。回收这些对象的任务只有交给程序员了(去根据语义和程序运行流程,选择恰当的时机去尽早释放各个引用)。然而这却失去了垃圾收集器存在的意义(自动回收可以回收的对象)。而弱引用可以很好解决这个问题。
只要垃圾收集器运行,弱引用所指向的对象就会被回收。 所以仅被弱引用关联的对象只能生存到下一次垃圾收集发生之前。
弱引用通过WeakReference类实现。
弱引用的生命周期比软引用短。
A a = new A();
WeakReference b = new WeakReference(a);
 a = null; //去掉强引用,此时只有弱引用指向a   a会在下次GC时被回收掉。
使用案例:ThreadLocalMap中的Entry数据结构中,key值(ThreadLocal变量的引用)就是弱引用。当某个key所指向的对象已经回收之后,这个key是个弱引用,会在下一次GC时自动回收掉,所以程序员不必再担心会造成内存泄漏。


4 虚引用

就是一个死亡通知单,让你知道对象已死。
虚引用也叫幽灵引用,它和没有引用没有区别,无法通过虚引取得对象实例或者访问对象的任何属性或函数
它唯一的作用就是当其指向的对象被回收之后,自己被加入到引用队列,用作记录该引用指向的对象已经被销毁。也就是说,一个对象关联虚引用唯一的作用就是在该对象被垃圾收集器回收之前会收到一条系统通知。

虚引用通过PhantomReference类来实现。

使用场景:
获取具体何时其引用的对象从内存中移除。
如一个浏览大图片的程序,内存只能容许一次加载一张图片时,在上一张图片对象回收之前,不能贸然加载下一张。但是内存回收是由垃圾收集器全权管理,我们不知道它会在哪个时刻回收了垃圾。所以当一个图片数据对象应该被回收时,可以利用虚引用来通知这个对象已经被回收,之后再继续加载下一张图片,以防止内存溢出。

猜你喜欢

转载自blog.csdn.net/fantalee/article/details/80841394