开发者社区> 问答> 正文

java垃圾回收机制GC判断可回收对象算法

java垃圾回收机制中,讲到GC判断可回收对象算法时,有一种可达性算法,不明白它如何解决对象循环引用问题的?

展开
收起
蛮大人123 2016-06-08 11:08:30 3228 0
2 条回答
写回答
取消 提交回答
  • 可达性算法可以分析出哪些对象在引用树上,那么剩下的对象就是可以回收的。如果是孤立的两个对象做循环引用,使用可达性算法分析后,这两个对象是不会在引用树上的,自然会把循环引用的两个对象判定为可回收的。循环引用问题是在另外一种标记计数的GC算法里才会有问题,这是一种比较古老的GC算法了,现代JVM已经不会采用这种方法了。

    2019-07-17 19:31:27
    赞同 展开评论 打赏
  • 我说我不帅他们就打我,还说我虚伪

    摘录周志明先生的《深入理解Java虚拟机》一书中对可达性算法的分析。
    首先,可达性算法基本思路是定义一些列称为"GC-Roots"的对象作为起始阶段,从这些节点向下搜索,搜索走过的路径称为引用链,当一个对象到GCRoots没有任何引用链时(即从GCRoots到这个对象不可达),则证明此对象是不可用的。
    其次,可达性算法中的不可达对象,在真正宣告“死亡”需要回收之前,至少要经过两轮标记过程:如果对象不可达,会被第一次标记并且进行一次筛选,筛选条件是次对象有没有必要执行finalize()方法。
    当对象没有覆盖finalize()方法或者这个方法以及被执行过了,那么久视为没有必要再执行。
    对于那些有必要执行finalize()方法的对象会被放在一个队列F-Queue中,然后稍后由虚拟机的一个线程去执行逐一执行队列中对象的finalize方法,如果线程在执行过程中发生了死循环,或者某个对象的finalize方法执行时间过长,导致队列其他对象一直处于等待,那么就会导致整个内存回收系统崩溃。
    第三,finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC会对F-Queue中的对象进行第二次小规模的标记,如果能在finalize中成功重新引用,第二次标记时就会将该对象从F-Queue集合中移除,而成功脱逃。
    所以,我理解你说的循环引用可能是想说不可达后突然又再次引用了,那么只能在finalize方法中再次引用而救活对象了。如果是普通循环中的循环操作引用,应该还没有涉及到垃圾回收、标记不可达的时候。
    最后,算法中的根对象通常是全局的静态成员对象,方法区中的常量引用对象,Native引用对象,线程栈中的引用对象等。

    2019-07-17 19:31:26
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
数据+算法定义新世界 立即下载
袋鼠云基于实时计算的反黄牛算法 立即下载
Alink:基于Apache Flink的算法平台 立即下载