引言
推荐阅读:
JVM高级特性与最佳实战(一)————JAVA内存区域
JVM高级特性与最佳实战(二)————对象的创建过程,内存布局,访问定位
JVM中字符串常量池的详细剖析
在java的垃圾回收算法中,最重要的莫过于如何判断对象已经死亡,那么我们究竟有几种方式判断对象已死呢?同时,在对象的访问定位中,提到了引用,那么引用只有一种方式么?接下来我们来探究一下。
对象已死?
在堆里边存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确认这些对象哪些还活着,哪些已经死了,即不可能被任何途径使用的对象。
- 引用计数算法
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加1,当引用失效时,计数器的值就减1;任何时刻计数器为0的对象就是不可能被使用的。
但是主流的JAVA虚拟机中没有选择这个引用计数法来管理内存,其中最主要的原因是他很难解决对象之间循环调用的问题。 - 可达性分析算法
通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为引用链。当一个对象到GCRoots没有任何引用链相连的时候,则证明此对象是不可用的。
在Java预言中,可作为GCRoots的对象包括以下几种:
(1)虚拟机栈中引用的对象
(2)方法区中类静态属性引用的对象
(3)方法区中常量引用的对象
(4)本地方法栈中JNI(Native)引用的对象
再谈引用
Java中的引用分为四种:
- 强引用: 强引用就是指在程序代码中普遍存在的,类似“Object obj = new Object()” 这类的引用。只要强引用还在,垃圾回收器永远不会回收被引用的对象
- 软引用:软引用是用来描述一些还有用但并非必须的对象。对于软引用关联的对象,在系统将要发生内存溢出异常之前,将会把这些对象列入回收范围之中进行第二次回收,如果这次回收还是没有足够的内存,才会抛出异常。Jdk提供了SoftReference类来实现软引用。
- 弱引用:弱引用比软引用还要弱,只能生存到下一次垃圾回收发生之前。JDK提供了WeekReference来实现弱引用。
- 虚引用也称为幽灵引用或者幻影引用,他是最弱的一种引用关系。一个对象是否有虚引用,完全不会对其生存空间造成影响,也无法通过虚引用来取得一个对象的实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收的时候收到系统通知。JDK提供了PhantomReference来实现虚引用。
总结
即使可达性分析算法中不可达的对象,也并非必须死亡的。要真正宣告一个对象的死亡,至少经历两次标记过程。
(1)如果对象在进行可达性分析后发现没有与GCRoots相链接的引用链,将进行第一次标记,并进行筛选,筛选的条件是此对象是否需要执行finalize()方法,如果是第一次覆盖finalize()方法,那么进入第二次标记。
(2)将上述的对象放入F-Queue队列中,这时虚拟机进行了一个低优先级的Finalizer线程去执行标记过程。如果此时对象重新引用了链上的任一对象,那么则移出队列,对象转为活的状态。
作者:select you from me
来源:CSDN
转载请联系作者获得授权并注明出处。