上篇文章已经介绍了JVM的垃圾回收算法与收集器的实现,垃圾回收算法的基石是引用可达性分析,引用的概念就显得尤其重要,本文就再谈一谈引用。java
Java中的引用至关于C++语言中的指针,经过指针/引用能够定位到另外一块内存地址中保存的数据,二者的不一样点在于C++语言中的指针分配的内存须要程序员编码回收,而Java中的引用则是 “自动” 回收内存。程序员
对于JVM的垃圾回收算法而言,引用的类型决定着被引用的对象的生命周期。算法
引用的类型按引用从强到弱排序包含:强引用(“Strong” Reference)、软引用(SoftReference)、弱引用(WeakReference)、虚引用(PhantomReference),对应 Java API 文档中的 java.lang.ref
包中。缓存
强、弱、软引用类型之间是能够直接进行转换的,这几种引用不在指向任何对象,而且在 finalize 方法执行后会转换成虚引用,最后被回收。框架
强引用就是最多见经过 new
关键字建立返回的引用,只要强引用指向着对象,那么垃圾收集器就不会回收此对象。编码
只有显示地将引用赋值为 null
或超过做用域,才能被垃圾回收器收集,回收时机要与具体的回收策略有关。.net
软引用相较强引用弱一些,当JVM认为堆内存不足时,垃圾收集器确保在抛出OutOfMemoryError 前,清理软引用指向的对象。线程
软引用一般用于实现内存敏感的缓存,当内存足够时,可保留缓存;当内存不足时,及时清理缓存,以避免耗尽内存。指针
弱引用比软引用还要弱,提供非强制的映射关系,会被 JVM 择机清理。code
好比维护一个对象,若是取获得就使用,取不到就从新实例化。相比软引用实现的缓存更不容易出现 OutOfMemoryError,经常出如今各大流行框架中做缓存实现。
虚引用又称幻象引用,是引用类型中最弱的一种,什么时候被 JVM 回收也不肯定,甚至于经过虚引用没法获取引用的对象。
只用于确保在 finalize方法执行后作一些后续操做,如清理等。
对应不一样引用的强弱,能够分为 强可达、软可达、弱可达、虚可达,除此以外还有不可达 五种可达性级别(reachability level)。
强引用对应的可达性级别,由一个或多个线程经过强引用访问获得。一般来讲一个线程建立了强引用对象,那么这个线程对这个对象就是强可达。
软引用对应的可达性级别,即只能经过软引用获取对象时。
弱引用对应的可达性级别,没法强引用、软引用访问,只能经过弱引用访问的对象,可达性级别为弱可达。是最接近 finalize 方法执行前的可达性级别。
虚引用(幻象引用)对应的可达性级别,没有强引用、软引用、弱引用关联的对象,通过 finalize 后,只有虚引用引用的对象,可达性级别为虚引用。
没有任何引用关联的对象,可达性级别为不可达,可直接被垃圾收集器清理。
经过对引用可达性分析,垃圾收集器能够在合适的时机回收一些不是很紧要的对象,防止内存了溢出的出现。
关于引用类型,总结以下:
同步更新于本人CSDN