强引用分析及在实际开发中的注意事项

在N年前在面试时就被问到Java的四种引用【强、软、弱、虚】的区别,而当时也是临时抱佛脚,在网上搜一些相关的博客来对其概念进行了解,随着撸码职业生涯的变长,也对这四种引用的特点大脑里面已经形成了一个固定思维了,对其使用场景也或多或少有些了解了,比如当时Android里面对于图片的加载都会用到ImageLoader,里面就使用了软引用来避免内存溢出,而我们在有些类中需要对Activity进行引用时,可能会使用虚引用来避免内存泄漏,但是!!没有系统的对其进行学习,所以接下来会系统详细的来学学它们。

首先来看一下强引用相关的理论:

  • 我们日常开发中所遇到的绝大多数引用均是强引用。
  • 如果对象拥有强引用,就表示它是可达的,那么垃圾收集器就不会将其回收。
  • 如果将某个强引用显示置为null,就表示该引用不再指向对象,若该对象没有其他引用指向它,那么在适当时机就会被垃圾收集器所回收。

关于强引用,其实貌似没啥可说的,都是实际大量在用的,但是理解它背后的意义还是很重要的,下面以jdk1.8系统类ArrayList中有块能体现强引用的代码为例进行说明,如下:

其中它的数据存放在elementData数组中,瞅一下:

这块代码都比较熟了,那怎么来体现强引用呢?

对于上面这个清空方法可能对于大家瞅一眼就过了,逻辑超级简单,没啥可理解的,其实不然,里面暗藏玄机的,其实我们在添加元素的时候就是一个强引用的体现,看一下添加方法:

好,那如果我们在clear()方法时不加这段代码有没有问题呢?

答案是!!!!不会有问题,为啥呢?

那。。系统ArrayList代码中为啥要加置null的代码呢?其实就是为了加速回收,其道理就如同上面描述的这个理论:

下面用图再来仔细体会一下加上这个置为null的好处:

以上是存放了5个元素的数组,接下来咱们调用了clear()方法,这里先看一下如果不将所有的元素置为null的情况,如果再添加新元素时,则会从0的位置添加,所以形态就变为:

好,这里就来仔细体会一下是不是在清空数组时不手动将所有元素置为null其实没啥问题,最终之前的旧元素都会被回收的,但是!!!假如说数组后面的元素一直没有被新元素给添加:

因为剩下的它们都是“强引用”,也就是说如果不手动将元素主动置为null程序逻辑倒不会有啥问题,但是会减慢这些不必要的老对像gc的速度,而下面来看一下正常会主动置为null的情况,一对比就晓得为啥系统在clear()时要主动将所有原因遍历置为Null的原因了,如下:

所以通过这个例子就能比较好的体会到强引用在实际中的意义,这个点比较简单,但是细细体会会加深对强引用的理解的。

posted on 2019-12-21 15:02  cexo  阅读(424)  评论(0编辑  收藏  举报

导航