【JVM从小白学成大佬】3.深入解析强引用、软引用、弱引用、幻象引用

  • 时间:
  • 浏览:0
  • 来源:幸运快3_快3规律_幸运快3规律

关于强引用、软引用、弱引用、幻象引用的区别,在什么都公司的面试题中经常 总出 ,意味许多小伙伴实在你这人知识点比较冷门,但实在你们你们儿在开发中经常 用到,如new三个 对象的很久什么都强引用的应用。

在java语言中,除了原始数据类型(boolean、byte、short、char、int、float、double、long)的变量,许多所有前会所谓的引用类型,指向各种不同的对象。理解那些引用的区别,对于掌握java对象生命周期和JVM内部内部结构相关机制非常有帮助。前会能够更深刻的理解底层对象生命周期、垃圾分类分类整理机制等,对设计可靠的缓存框架、诊断应用OOM等大问题也大有裨益。

这并也有应用主要的区别体现在对象不同的可达性状态和对垃圾分类分类整理的影响,你们你们儿之间的可达性状态都都可以参看下图:

1.强引用(strong reference)

强引用什么都你们你们儿最常见的普通对象引用(如new 三个 对象),只要还有强引用指向三个 对象,就表明此对象还“活着”。在强引用身后,即使JVM内存空间不足英文,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),让守护应用应用程序异常终止,什么都会靠回收强引用对象来解决内存不足英文的大问题。对于三个 普通的对象,意味没有许多的引用关系,只要超过了引用的作用域意味显式地将相应(强)引用赋值为null,就意味此对象都都可以被垃圾分类分类整理了。但要注意的是,并前会赋值为null后就立马被垃圾回收,具体的回收时机还是要看垃圾分类分类整理策略的。

如Object obj = new Object();

2.软引用(soft reference)

软引用相对强引用要弱化许多,都都可以让对象豁免许多垃圾分类分类整理。当内存空间足够的很久,垃圾回收器不多回收它。没有当JVM认定内存空间不足英文时才会去回收软引用指向的对象。JVM会确保在抛出OOM前清理软引用指向的对象,或者JVM是很聪明的,会尽意味优先回收长时间闲置不多的软引用指向的对象,对那些刚构建的或刚使用过的软引用指向的对象尽意味的保留。基于软引用的那些行态,软引用都都可以用来实现什么都内存敏感点的缓存场景,即意味内存还有空闲,都都可以暂时缓存许多业务场景所需的数据,当内存不足英文时就都都可以清理掉,等后面 再须要时,都都可以重新获取并再次缓存。曾经就确保在使用缓存提升性能的同去,不多意味耗尽内存。

软引用通常都都可以和三个 引用队列(ReferenceQueue)联合使用,意味弱引用所引用的对象被垃圾回收,java虚拟机就会把你这人软引用加入到与之关联的引用队列中。

Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj);
obj = null;
//或者会返回null
sf.get(); 

通很久面 的代码都都可以看出sf是对obj的三个 软引用,当sf对象还没有被销毁前,sf.get()都都可以获取到你这人对象,意味已被销毁,则返回null。

正确使用软引用的示例代码如下:

SoftReference<List<Foo>> ref = new SoftReference<List<Foo>>(new LinkedList<Foo>());
 
// somewhere else in your code, you create a Foo that you want to add to the list
List<Foo> list = ref.get();
if (list != null)
{
    list.add(foo);
}
else
{
    // list is gone; do whatever is appropriate
} 

在使用软引用的很久须要检查引用否是为null。意味垃圾分类分类整理器意味在任意时刻回收软引用,意味不做否是null的判断,意味会总出 NullPointerException的异常。

总的来说,软引用是用来描述许多还有用但无须必需的对象。对于软引用关联着的对象,在系统将要位于内存溢出异常很久,意味把那些对象列进回收范围之中进行第二次回收。意味这次回收还没有足够的内存,才会抛出内存溢出异常。

3.弱引用(weak reference)

弱引用指向的对象是并也有十分临近finalize状态的状态,当弱引用被清除的很久,就符合finalize的条件了。弱引用与软引用最大的区别什么都弱引用比软引用的生命周期更短暂。垃圾回收器会扫描它所管辖的内存区域的过程中,只要发现弱引用的对象,不管内存空间与否是空闲,前会立刻回收它。如同前面我知道你过的,具体的回收时机还是要看垃圾回收策略的,或者那些弱引用的对象并前会说只要达到弱引用状态就会立马被回收。

基于弱引用的那些行态,弱引用同样都都可以应用在什么都须要缓存的场景。

Object obj = new Object();
WeakReference<Object> wf = new WeakReference<Object>(obj);
obj = null;
//或者会返回null
wf.get();
//返回否是被垃圾回收器标记为即将回收的垃圾
wf.isEnQueued();

4.幻象引用(phantom reference)

幻象引用,前会被说成是虚引用或疾速引用。幻象引用无须会决定对象的生命周期。即意味三个 对象仅持有虚引用,就相当于没有任何引用一样,在任几很久都意味被垃圾回收器回收。没有通过它访问对象,幻象引用仅仅是提供了并也有确保对象被finalize很久,做许多事情的机制(如做所谓的Post-Mortem清理机制),前会人利用幻象引用监控对象的创建和销毁。

Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj);
obj=null;
//永远返回null
pf.get();
//返回否是从内存中意味删除
pf.isEnQueued(); 

幻象引用的get最好的法律法律依据永远返回null,主要用于检查对象否是意味从内存中删除。

5.生存还是死亡

通很久面 对并也有引用类型的分析,你意味发现许多对象即使不可达,但也无须是“非死不可”的,你这人很久它们暂时位于“缓刑”阶段,要真正组阁 三个 对象死亡,相当于要经历两次标记过程意味对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它意味被第一次标记或者进行一次筛选,筛选的条件是此对象与否是必要执行finalize()最好的法律法律依据。当对象没有覆盖finalize()最好的法律法律依据,意味finalize()最好的法律法律依据意味被虚拟机调用过,虚拟机将这并也有状态都视为“没有必要执行”。

意味你这人对象被判定为有必要执行finalize()最好的法律法律依据,没有你这人对象意味放置在三个 叫做F-Queue的队列之中,并在稍后被三个 由虚拟机自动建立的、低优先级的Finalizer守护应用应用程序去执行它。这里所谓的“执行”是指虚拟意味触发你这人最好的法律法律依据,但无须承诺会等待它运行刚结束了了,曾经做的意味是,意味三个 对象在finalize()最好的法律法律依据中执行缓慢,意味位于了死循环(更极端的状态),将很意味会意味F-Queue队列中许多对象永久位于等待,甚至意味整个内存回收系统奔溃。finalize()最好的法律法律依据是对象逃脱死亡命运的最后一次意味,稍后GC将对F-Queue中的对象进行第二次小规模的标记,意味对象要在finalize()中成功拯救当时人——只要重新与引用链上的任何三个 对象建立关联即可。譬如把当时人(this关键字)赋值给某个类变量意味对象的成员变量,那在第二次标记时它将被移除出“即将回收”的集合;意味对象这很久还没有逃脱,那基本上它就真的被回收了。

任何三个 对象的finalize()最好的法律法律依据都只会被系统自动调用一次,意味对象面临下一次回收,它的finalize()最好的法律法律依据不多被再次执行。

6.总结

对象的可达性是JVM垃圾分类分类整理器决定怎样才能解决对象的三个 重要考虑指标

所有引用类型前会抽象类java.lang.ref.Reference的子类,子类里提供了get()最好的法律法律依据。通很久面 的分析中都都可以得知,除了幻象引用(意味get永远返回null),意味对象还没有被销毁,都都都可以通过get最好的法律法律依据获取原有对象。实在有个非常关键的注意点,利用软引用和弱引用,你们你们儿都都可以将访问到的对象,重新指向强引用,也什么都人为的改变了对象的可达性状态。什么都对于软引用、弱引用类似,垃圾分类分类整理器意味会位于二次确认的大问题,以确保位于弱引用状态的对象没有改变为强引用。

或者有个大问题,意味你们你们儿错误的保持了强引用(比如,赋值给了static变量),没有对象意味就没有意味变回类似弱引用的可达性状态了,就会产生内存泄露。什么都,检查弱引用指向对象否是被垃圾分类分类整理,也是诊断与否是特定内存泄露的三个 思路,你们你们儿的框架使用到弱引用又怀疑有内存泄露,就都都可以从你这人淬硬层 检查。

对于软引用、弱引用、幻象引用都都可以配合引用队列(ReferenceQueue)来使用,有点儿是幻象引用,get最好的法律法律依据只返回null,意味再不指定引用队列,基本就没有任何意义了。

后面 分析了并也有引用类型的使用,熟悉这几种应用类型对深入理解JVM也大有裨益。

热门阅读:

【JVM从小白学成大佬】1.开篇【JVM从小白学成大佬】2.Java虚拟机运行时数据区

参考

《深入理解Java虚拟机》

http://www.kdgregory.com/index.php?page=java.refobj