持有引用

再谈持有引用之前,我们需要了解一下可达性分析算法

1、可达性分析算法

在java中,我们是通过可达性分析来判断对象是否存活,基本思想是:通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连,也就是从GC Roots到这个对象不可达时,则证明此对象是不可用的,如图:object5、object6、object7虽然相互关联,但是他们到GC Roots是不可达的,所以被判定为可回收对象。

可作为GC Roots的对象包括几种:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象;
  • 方法区中类静态属性引用的对象;
  • 方法区中常量引用的对象;
  • 本地方法栈中JNI(即一般说的Native)方法引用的对象; 

2、再谈引用

2.1 Reference引用对象


有了上面的图,就很好理解了,通过可达性分析算法判断对象的引用链是否可达,判断对象是否存活都与“引用”有关。

Java中的引用定义很传统,如果reference类型的数据中存储的之代表的是另一块内存的其实地址,就称这块内存代表着一个引用,这种定义很存粹,但过狭隘,一个对象在这种定义之下只有被引用和没有被引用两种状态;

因此我们希望描述这样一种情景:想继续持有某个对象的引用,希望以后还能够访问该对象,但同时也希望允许垃圾回收器释放它,这时就应该使用Reference对象;普通引用-->Reference对象-->目标对象

2.2 Reference引用四种分类


java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、若引用(Weak Reference)、虚引用(Phantom Reference),强度由强到弱。

  • 强引用类似“Object obj = new Object()”这类引用,只要引用还在,垃圾回收器永远不会回收掉被引用对象;
  • 软引用是用来描述一些还有用但并非必须的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行二次回收。如果这次还没有足够的内存,才会抛出内存溢出异常,也可以说用以实现内存敏感的高速缓存
  • 弱引用用来描述非必须对象,被弱引用关联的对象只能生存到下一次垃圾收集器发生之前,当垃圾回收器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象;
  • 虚引用也成为幽灵引用或者幻影引用,它是最弱的一种引用关系,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过一个虚引用来取得一个对象的实例;唯一目的就是在这个对象被垃圾回收器回收时收到一个系统通知;

参考资料:《think in java》、《深入理解java虚拟机》

博客:https://www.cnblogs.com/ixenos/p/5658932.html

           

发布了59 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/hou_shiyu/article/details/99689150