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

  • 时间:
  • 浏览:1
  • 来源:极速快3_快3平台网址_极速快3平台网址

关于强引用、软引用、弱引用、幻象引用的区别,在全都公司的面试题中突然出显,机会全都小伙伴随便说说这名 知识点比较冷门,但随便说说亲戚朋友在开发中突然用到,如new三个 对象的那我全都我强引用的应用。

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

这这名应用主要的区别体现在对象不同的可达性情形和对垃圾埋点的影响,朋友之间的可达性情形可不都能能参看下图:

1.强引用(strong reference)

强引用全都我亲戚朋友最常见的普通对象引用(如new 三个 对象),我希望还有强引用指向三个 对象,就表明此对象还“活着”。在强引用转过身,即使JVM内存空间不足英文,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),让系统tcp连接异常终止,全都我会靠回收强引用对象来处里内存不足英文的问題。对于三个 普通的对象,机会那么 全都的引用关系,我希望超过了引用的作用域机会显式地将相应(强)引用赋值为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系统tcp连接去执行它。这里所谓的“执行”是指虚拟机会触发这名 最好的法子,但并不承诺会等待它运行刚开始英文,那我做的由于是,机会三个 对象在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