Gc如何判断对象可以被回收?

Gc如何判断对象可以被回收?

1 引用计数器

引用计数法的算法思路:给对象增加一个引用计数器,每当对象增加一个引用计数器+1,失去一个引用-1,所以当计数器是0的时候对象就没有引用了,就会被认为可回收垃圾

引用计数法,可能会出现A引用了B,B又引用了A,这时候就算他们都不再使用了,但因为他们相互引用,计数器=1,永远无法被回收,这是这种方法很大的劣势,但效率较高

    在主流的JVM中没有选用引用计数法来管理内存(比如java),最主要的原因是引用计数法无法解决对象的循环引用问题。

在主流的JVM中没有选用引用计数法来管理内存(比如java),最主要的原因是引用计数法无法解决对象的循环引用问题

2 可达性分析

Java并不采用引用计数法来判断对象是否是垃圾,而采用“可达性分析”来进行判断

    可达性分析的算法思路:通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为“引用链”,当一个对象到 GC Roots 没有任何的引用链相连时(即从 GC Roots 到这个对象不可达)时,证明此对象不可用(视为垃圾)。以下图为例:

img

虽然Object5-7是有联系的,但是他们到gc roots不可达,因此他们会被判定为可回收的垃圾对象

java中可作为GC Roots的对象包含以下几种:

    1.虚拟机栈(栈帧中的本地变量表)中引用的对象

    2.方法区中静态引用的对象

    3.方法区中常量引用的对象

    4.本地方法栈中JNI(Native方法)引用的对象

可达性算法中的不可达对象并不是立即死亡的,对象拥有一次自我救赎的机会。对象被系统宣告死亡至少要经历两次标记过程:第一次是经过可达性分析发现没有与GC Roots相连接的引用链,第二次是由虚拟机自动创立的Einalizer队列中判断是否需要执行finalize()方法

当对象变成(GC Roots)不可达时,GC会判断对象是否覆盖了finalize()方法,若未覆盖则直接将其回收。否则若对象未执行finalize()方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize()方法。执行finalize()方法完毕后,GC会再次判断对象是否可达,若不可达则进行回收,否则对象"复活"

每个对象只能除法一次finalize()方法z

由于finalize()方法运行代价奥昂不确定性大,无法保证各个对象的调用顺序,不推荐大家使用,建议遗忘。————————————————
版权声明:本文为CSDN博主「C位出道_2022」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_53611007/article/details/120609856

posted @ 2022-01-13 23:49  牛亚龙  阅读(289)  评论(0编辑  收藏  举报