首页 > 编程语言 >垃圾回收算法(2)-根搜索算法

垃圾回收算法(2)-根搜索算法

时间:2022-09-20 15:47:00浏览次数:74  
标签:finalize 对象 System 搜索算法 HOOK 算法 GC 垃圾 SAVE

前言

相对于引用计数算法而言,根搜索算法不仅同样具备实现简单和执行高效等特点,更重要的是该算法可以有效的解决在引用记数法中一些已经死亡的对象因为相互引用而导致的无法正确被
标记的问题,防止内存泄漏的发生。

算法原理

根搜索算法是以根对象集合为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达(使用根算法后,内存中的存活对象都会被根对象集合直接或间接连接着)
如果目标对象不可达,就意味着该对象已经死亡,便可将其标记为垃圾对象。

在根搜索算法中不可达的对象,也并非是“非死不可”,这时候他们暂时处于“缓行”阶段,要真正宣告一个对象死亡,至少要经历2次标记过程。如果对象在进行根搜索后发现并没有与GC Roots相连接的
引用链,那么它将会被第一次标记并进行一次筛选,筛选的条件是这个对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,
虚拟机将这两种情况都视为没有必要执行finalize()方法。如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会被放置在一个名为F-Queue的队列之中,并在稍后有一条虚拟机自动建立、
低优先级的 finalize的线程去执行。虚拟机会触发finalize()方法,但并不承诺等待它执行结束。finalize()方法是对象逃脱死亡的最后一次F-Queue中的对象机会。GC将会对F-QUEUEF-Queue中的对
象进行第二次小规模的标记,如果某个对象重新与GC Roots引用链上的对象建立关联关系,那么第二次标记时它将被移除F-Queue。如果对象这个时候还没有逃脱,那他就真的离死不远了。

就拿上图来说,ObjectD和ObjectE是互相关联的,但是由于GC roots到这两个对象不可达,所以最终D和E还是会被当做GC的对象,上图若是采用引用计数法,则A-E五个对象都不会被回收。

逃脱回收实验

public class FinalizeEscapeGC {

    public static FinalizeEscapeGC SAVE_HOOK = null;
    
    public void isAlive(){
        System.out.println("i am still alive");
    }
    
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed");
        FinalizeEscapeGC.SAVE_HOOK = this;
    }

    public static void main(String[] args) throws InterruptedException {
        SAVE_HOOK = new FinalizeEscapeGC();
        //对象第一次拯救自己
        SAVE_HOOK = null;
        System.gc();
        //因为Finalize方法的优先级很低,暂停5秒
        Thread.sleep(500);
        if(SAVE_HOOK != null){
            SAVE_HOOK.isAlive();
        }else{
            System.out.println("i am dead");
        }
        //以下代码与上面的完全相同,但是这次却自救失败了
        SAVE_HOOK = null;
        System.gc();
        //因为Finalize方法的优先级很低,暂停5秒
        Thread.sleep(500);
        if(SAVE_HOOK != null){
            SAVE_HOOK.isAlive();
        }else{
            System.out.println("i am dead");
        }
    }
}

控制台输出

finalize method executed
i am still alive
i am dead

从代码的运行结果看出,SAVE_HOOK对象的finalize()方法确实被GC收集器出发过,并且在被手机前成功逃脱了。另一个值得注意的地方是,代码中有2段完全一样的代码,执行结果是一次成功,一次失败,
这是因为热河一个对象的finalize()方法都会被系统自动调用一次,如果对象面临下一次回收,他的finalize()方法不会被再次执行,因此后面的方法执行自救失败了。

标签:finalize,对象,System,搜索算法,HOOK,算法,GC,垃圾,SAVE
From: https://www.cnblogs.com/leepandar/p/16711263.html

相关文章

  • 垃圾回收算法(1)-引用计数法
    算法原理引用记数法在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活的对象,哪些是已经死亡的对象,只有被标记为已经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的......
  • Problem P19. [算法课贪婪]三角形的最大周长
    贪心:选三个最长的边组成三角形,如果最长的三个边不能组成,那么这时候无论把第二和第三大的边换成什么都不可能能够和最大的边组成三角形,这时候就必须把最大的边给换掉,把最......
  • 计算机系统结构大题精讲-考点一页面替换算法
    一、FIFO页面替换算法1、有一个虚拟存储器,主存有4个实页,页号为0-3;程序有8个虚页,页号为0-7;采用FIFO算法和全相连映像。给出如下程序页地址流:2、3、5、2、4、0、1、2、4、6......
  • Problem P20. [算法课蛮力法]种花问题
    我写的并不好,力扣上有比这更好的方法我的思路:从头遍历数组,检查位置是否能放下花,能放就放下,然后检查下一个位置,注意放下之后就改变了数组。然后就是注意前后数组越界,注意......
  • V8 的垃圾回收机制
    一、基本概念 1.1对象/头/域对象这个词,在不同的使用场合其意思各不相同。比如,在面向对象编程中,它指“具有属性和行为的事物”,然而在GC的世界中,对象表示的是“通过应......
  • 学习-数组相关算法-两数之和
    obj[1]=111letobj={"5":222}console.log(obj[5])////222console.log(obj['5'])//222//console.log(obj.5)这样写会报错obj[1]=111console.log(JSO......
  • 数据结构算法与应用:C++语言描述(第2章 程序性能)
    目录2.1引言2.2空间复杂性(spaceComplexity)\(S_p(n)\)2.2.1空间复杂性的组成2.2.2举例2.3时间复杂性(timecomplexity)\(T(n)\)2.3.1时间复杂性的组成2.3.2操作计......
  • 数据结构算法与应用:C++语言描述(第2章 程序性能)
    目录2.1引言2.2空间复杂性(spaceComplexity)\(S_p(n)\)2.2.1空间复杂性的组成2.2.2举例2.3时间复杂性(timecomplexity)\(T(n)\)2.3.1时间复杂性的组成2.3.2操作计......
  • fh-2022算法考试编程题-2
    小A有一套特殊的卡牌,他们是1-N的数字的排列,每个数字有且仅有一张卡。小A在洗牌之后,会把卡牌并排放在地上。小A总是在通过卡牌的交换位置来获得1,2,3....N的序列。假如初......
  • 模拟退火算法
    ​ 模拟退火算法来源于固体退火原理,是一种基于概率的算法,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温......