垃圾回收算法|GC标记-清除算法
本文是《垃圾回收的算法与实现》读书笔记 什么是GC标记-清除算法(Mark Sweep GC) GC 标记-清除算法由标记阶段和清除阶段构成。在标记阶段会把所有的活动对象都做上标记,然后在清除阶段会把没有标记的对象,也就是非活动对象回收。 名词解释: 在 GC 的世界里对象指的是通过应用程序利用的数据的集合。是 GC 的基本单位。一般由头(header)和域(field)构成。 活动对象:能通过引用程序引用的对象就被称为活动对象。(可以直接或间接从全局变量空间中引出的对象) 非活动对象:不能通过程序引用的对象呗称为非活动对象。(这就是被清除的目标) 标记-清除算法的伪代码如下所示: func mark_sweep(){ mark_phase() // 标记阶段 sweep_phase() // 清除阶段 } 标记阶段 标记阶段就是遍历对象并标记的处理过程。 标记阶段伪代码如下: func mark_phase(){ for (r : $roots) // 在标记阶段,会给所有的活动对象打上标记 mark(*r) } func mark(){ if (obj.mark == False) obj.mark = True // 先标记找出的活动对象 for (child: children(obj)) // 然后递归的标记通过指针数组能访问到的对象 mark(*child) } 这里 $root 是指针对象的起点,通过$root 可以遍历全部活动对象。 下图是标记前和标记后内存中堆的状态 清除阶段 在清除阶段,collector 会遍历整个堆,回收没有打上标记的对象(垃圾),使其能再次利用。 sweep_phase() 函数伪代码实现如下: func sweep_phase(){ sweeping = $heap_start // 首先将堆的首地址赋值给 sweeping while(sweeping < $head_end){ if(sweeping.mark == TRUE) // 如果是标记状态就设为 FALSE,如果是活动对象,还会在标记阶段被标记为 TRUE sweeping.mark == FALSE else: sweeping.next = $free_list // 将非活动对象 拼接到 $free_list 头部位置 $free_list = sweeping sweeping += sweeping.size } } size 域指的是存储对象大小的域,在对象头中事先定义。 ...