JVM系列之三 再谈引用

前言

上篇文章已经介绍了JVM的垃圾回收算法与收集器的实现,垃圾回收算法的基石是引用可达性分析,引用的概念就显得尤其重要,本文就再谈一谈引用。java

1、引用是什么?

Java中的引用至关于C++语言中的指针,经过指针/引用能够定位到另外一块内存地址中保存的数据,二者的不一样点在于C++语言中的指针分配的内存须要程序员编码回收,而Java中的引用则是 “自动” 回收内存。程序员

对于JVM的垃圾回收算法而言,引用的类型决定着被引用的对象的生命周期。算法

2、引用的类型

引用的类型按引用从强到弱排序包含:强引用(“Strong” Reference)、软引用(SoftReference)、弱引用(WeakReference)、虚引用(PhantomReference),对应 Java API 文档中的 java.lang.ref 包中。缓存

强、弱、软引用类型之间是能够直接进行转换的,这几种引用不在指向任何对象,而且在 finalize 方法执行后会转换成虚引用,最后被回收。框架

一、强引用(“Strong” Reference)

强引用就是最多见经过 new 关键字建立返回的引用,只要强引用指向着对象,那么垃圾收集器就不会回收此对象。编码

只有显示地将引用赋值为 null 或超过做用域,才能被垃圾回收器收集,回收时机要与具体的回收策略有关。.net

二、软引用(SoftReference)

软引用相较强引用弱一些,当JVM认为堆内存不足时,垃圾收集器确保在抛出OutOfMemoryError 前,清理软引用指向的对象。线程

软引用一般用于实现内存敏感的缓存,当内存足够时,可保留缓存;当内存不足时,及时清理缓存,以避免耗尽内存。指针

三、弱引用(WeakReference)

弱引用比软引用还要弱,提供非强制的映射关系,会被 JVM 择机清理。code

好比维护一个对象,若是取获得就使用,取不到就从新实例化。相比软引用实现的缓存更不容易出现 OutOfMemoryError,经常出如今各大流行框架中做缓存实现。

四、虚引用(PhantomReference)

虚引用又称幻象引用,是引用类型中最弱的一种,什么时候被 JVM 回收也不肯定,甚至于经过虚引用没法获取引用的对象。

只用于确保在 finalize方法执行后作一些后续操做,如清理等。

3、引用的可达性

对应不一样引用的强弱,能够分为 强可达软可达弱可达虚可达,除此以外还有不可达 五种可达性级别(reachability level)。

一、强可达(Strongly Reachable)

强引用对应的可达性级别,由一个或多个线程经过强引用访问获得。一般来讲一个线程建立了强引用对象,那么这个线程对这个对象就是强可达。

二、软可达(Softly Reachable)

软引用对应的可达性级别,即只能经过软引用获取对象时。

三、弱可达(Weakly Reachable)

弱引用对应的可达性级别,没法强引用、软引用访问,只能经过弱引用访问的对象,可达性级别为弱可达。是最接近 finalize 方法执行前的可达性级别。

四、虚可达(Phantom Reachable)

虚引用(幻象引用)对应的可达性级别,没有强引用、软引用、弱引用关联的对象,通过 finalize 后,只有虚引用引用的对象,可达性级别为虚引用。

五、不可达(unreachable)

没有任何引用关联的对象,可达性级别为不可达,可直接被垃圾收集器清理。

总结

经过对引用可达性分析,垃圾收集器能够在合适的时机回收一些不是很紧要的对象,防止内存了溢出的出现。

关于引用类型,总结以下:

  1. 强引用,只要对象引用可达,对象使用的内存就一直被占用。
  2. 软引用,对象使用的内存一直占用,直到 JVM 认为有必要回收内存。
  3. 弱引用,对象使用的内存一直占用,直到下一次 GC。
  4. 虚引用,执行 get 方法永远返回空,能够在 finalize 方法执行后作一些操做。

同步更新于本人CSDN

相关文章
相关标签/搜索