标记-清除算法
第一个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 申请分块时, 搜索空闲链表并寻找大小合适的分块,清除阶段已经把垃圾对象连接到空闲链表.
-
合并

标记清除算法是GC的基础,包括标记和清除两个阶段。标记阶段从根开始递归标记所有可达对象,清除阶段回收未标记对象,形成空闲链表。此算法简单但存在碎片化问题,优化策略包括多空闲链表、位图标记和延迟清除等。
最低0.47元/天 解锁文章
2083

被折叠的 条评论
为什么被折叠?



