垃圾回收算法详解(一)基础算法

    xiaoxiao2021-03-25  99

    一算法图谱二算法介绍 1标记清除法2引用计数法3复制法4标记压缩法

    一、算法图谱

    二、算法介绍

    2.1标记清除法

    标记清除法分为标记阶段与清除阶段,先来看个图解。

    上图描述:从根节点出发,标记所有能从根节点到达的节点。

    上图描述:从堆开头开始遍历,遇到未被标记的节点就将其插入到空闲链表中,遇到已标记的节点则清除其标记。


    伪代码描述如下

    以上是垃圾标记清除阶段伪代码,总过程就是先标记,后清除。即每次触发GC时都会执行这两步操作。


    如下是分配内存的伪代码,算法逻辑为:

    如果刚好找到的块的size与所需size相等,则直接返回该块; 如果找到的块的size大于所需size,则将该块分割成大小为size和剩余size的两部分,将size那部分返回。



    2.2引用计数法

    与标记清除法不同,引用计数法并没有明确的启动GC的语句。

    标记清除法会在分块不够时让mutator触发garbage_collect()函数来执行GC操作。

    而引用计数法则是在mutator正常处理流程中通过增减计数器的值来进行内存管理,从而达到GC的效果。


    引用计数法主要涉及两个函数,new_obj()与update_ptr()函数,即开辟内存块阶段和更新引用阶段。伪代码如下:

    上图:在分配阶段,如果找到合适的块,则将该块计数器加1.

    上图: update_ptr(ptr, obj)函数是将ptr指针指向obj

    首先要对obj的计数器加1

    然后将ptr指针之前指向的域的计数器减1

    最后将ptr指向obj

    注意:为什么要先执行inc_ref_cnt(obj)后执行dec_ref_cnt(*ptr)呢? 这是因为,当obj与*ptr表示同一个对象时,如果先执行dec_ref_cnt(*ptr),那么该对象的计数器值就是0,则该对象会被回收了,那么再执行inc_ref_cnt(obj)会引发BUG。

    上图:dec_ref_cnt(obj)先对自己的计数器减1,然后遍历自己的子节点,将子节点的计数器减1。

    reclaim(obj)函数表示将obj插入到空闲链表中。

    2.3复制法

    GC复制算法将内存空间分为两个相同大小的From区域与To区域,

    执行GC操作的过程就是把From区域里的所有活动对象复制到To区域,

    然后将原空间的所有对象回收掉,最后将From和To角色互换,新的To又变成了存放活动对象的From

    好了,废话不多说,先来看一波图解

    图解的细节可能不够,再来看一波伪代码

    如上图:复制操作先将空闲链表头指向To空间的起始位置,

    然后从root节点开始遍历From空间,将From空间的所有活动节点复制到To空间

    最后清除From空间里所有对象,并把From空间和To空间互换

    如上图:

    copy(obj)函数是将处于From空间的obj复制到To空间的操作,

    其中obj对象有两个标志位: tag表示是否已经被复制,目的是防止子对象被多次复制; forwarding表示From空间中的obj对象在To空间中的复本的位置。copy函数最后会返回该值。

    copy_data($free, obj, obj.size)表示将obj复制到$free链表空间中去,大小为obj.size。

    每次复制完毕,将$free指针向后移动obj.size个单位,使下一个复制的节点紧挨着放在前一个节点后面。

    如上图:GC复制算法的分配操作

    第一步:判断空闲区域加上size大小后,是否超过整个栈空间的一半。其中HEAP_SIZE表示From空间与To空间大小之和。

    第二步:如果超过了,则执行复制操作。如果复制之后,所需的空间还是不够,则抛出异常。

    第三步:在free中开辟一个所需的size大小的空间给obj,然后将$free指针向后移动size位。 最后返回obj。

    2.4标记压缩法

    标记压缩法:顾名思义,分为标记阶段与压缩阶段。其中标记阶段与标记清除法一样,压缩阶段是讲所有活动对象紧挨着放在一起。先来一波图解吧。

    标记阶段很好理解,压缩阶段可能会有些复杂,别急,再来看一波伪代码。

    如上图:标记压缩算法的压缩阶段分为三步 1.设定forwarding指针 2.更新指针 3.移动对象

    转载请注明原文地址: https://ju.6miu.com/read-26422.html

    最新回复(0)