Java的引用——强引用 、软引用、弱引用、虚引用

先知

  • Java中除了八大基本数据类型,其他都是引用类型,指向各种不同的对象。
  • java.lang.ref包下提供了引用对象类(共包括五个类:PhantomReference、Reference、ReferenceQueue、SoftReference、WeakReference),支持在某种程度上与垃圾回收器GC(垃圾回收机制回收某个对象主要是看是否有引用指向这个对象)之间的交互。
  • 对象分类:强可达对象、软可达对象、弱可达对象、虚可达对象、不可达对象
    强可达对象:如果某一线程可以不必遍历所有引用对象而直接到达一个对象,则该对象是强可达对象。新创建的对象对于创建它的线程而言是强可达对象。 
    软可达对象:如果一个对象不是强可达对象,但通过遍历某一软引用可以到达它,则该对象是软可达对象。 
    弱可达对象:如果一个对象既不是强可达对象,也不是软可达对象,但通过遍历弱引用可以到达它,则该对象是弱可达对象。当清除对某一弱可到达对象的弱引用时,便可以终止此对象了。 
    虚可达对象:如果一个对象既不是强可达对象,也不是软可达对象或弱可达对象,它已经终止,并且某个虚引用在引用它,则该对象是虚可达对象。
    不可达对象:最后,当不能以上述任何方法到达某一对象时,该对象是不可达对象,因此可以回收此对象。

Java的引用

如上所知,Java中把对象的引用分成了四个级别,分别为:强引用 、软引用、弱引用、虚引用。

而Java中提供这四种引用类型主要有两个目的:划分对象不同的可达性GC对对象回收的影响

强引用

  • 强引用:是指创建一个对象并把这个对象赋给一个引用变量。
  • 表现:Object object =new Object();
  • 特点:只要强引用存在,GC永远不会回收该对象。JVM内存空间不足时,它宁愿抛出OutOfMemory错误,也不会回收该对象。如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,就可以根据具体的垃圾回收机制被回收。

软引用

  • 软引用:SoftReference,如果一个对象具有软引用,内存空间足够时,GC就不会回收它。
  • 特点:
  1. SoftReference保存对一个Java对象的软引用,该软引用的存在不妨碍GC对该对象的回收。也就是说,在GC对这个对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用;一旦GC回收该对象之后,get()方法将返回null。
  2. 软引用对象最常用于实现内存敏感的缓存,比如图片缓存。
  3. 使用软引用能防止MemoryLeak,增强程序的健壮性。

弱引用

  • 弱引用:WeakReference,弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。
  • 举例:为什么Android自定义内部类AsyncTask要使用WeakReference?
  • 因为内部类MyAsyncTask会隐式持有外部类Activity,当结束Activity时MyAsyncTask持有的Activity是弱引用,那么Activity能被正常GC,不会引发内存泄漏。

虚引用

  • 虚引用:PhantomReference,最弱的一种引用关系,如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被GC回收。
  • 为了确保可回收的对象仍然保持原状,虚引用的指示对象不能被获取,即虚引用的get方法总是返回 null。虚引用唯一目的是能在这个对象被GC回收时收到一个系统通知。

表格对比

引用类型 GC回收时机 用途
强引用 不回收 最常使用
软引用 内存不足时回收 缓存、防止内存泄漏等
弱引用 每次GC时回收 缓存、防止内存泄漏等
虚引用 随时可能被回收

在对象被GC回收时收到一个系统通知

总结

总的来说,强引用是我们最常使用的,而对于其他三种类型的引用,使用得最多的就是软引用和弱引用。这两种既有相似之处又有区别,它们都是用来描述非必需对象的,但是被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在每次GC时会被回收。

发布了55 篇原创文章 · 获赞 61 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Agg_bin/article/details/93502712