标记-清除算法
第一个GC算法
标记清除算法有两个阶段: 标记阶段和清除阶段 。标记是将活动对象做标志, 也就是识别非活动对象。清除就是非活动对象回收的过程
标记时候,会去标志所有的对象,因此,耗时与对象的总数是成正比的
因为会遍历所有对象,一般会用到两种搜索算法:
- 深度优先搜索
- 广度优先搜索
深度优先比广度优先搜索更能压低内存使用量, 二是可以将有关系的对象,放入到邻近的位置上
-
标记:
通过根 递归地标记能访问到的对象, 这样根及其子对象都会被扫描到,并被标识
mark(obj){
if(obj.mark == FALSE)
obj.mark = TRUE
for(child : children(obj))
mark(*child)
}
-
清除
在清除阶段中,collector 会遍历整个堆,回收没有打上标记的对象(即垃圾),使其能再
次得到利用。并且一般会维护一个空闲链表,用于被回收空间的再次利用sweep_phase(){ sweeping = $heap_start while(sweeping < $heap_end) if(sweeping.mark == TRUE) sweeping.mark = FALSE else sweeping.next = $free_list $free_list = sweeping sweeping += sweeping.size } #heap_start堆开始位置 heap_end 堆尾 free_list 空闲链表
-
分配空间
当mutator 申请分块时, 搜索空闲链表并寻找大小合适的分块,清除阶段已经把垃圾对象连接到空闲链表.
-
合并