码迷,mamicode.com
首页 > 编程语言 > 详细

GC标记-清除算法(Mark Sweep GC)

时间:2018-11-09 21:36:22      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:两种   优先   利用   碎片   page   设定   建立   速度   情况   

  • 世界上第一个GC算法,由 JohnMcCarthy 在1960年发布。

标记-清除算法由标记阶段和清除阶段构成。

  1. 标记阶段就是把所有的活动对象都做上标记的阶段。

    • 标记阶段就是“遍历对象并标记”的处理过程。
    • 标记阶段经常用到深度优先搜索。
  2. 清除阶段就是把那些没有标记的对象,也就是非活动对象回收的阶段。

    • 清除阶段collector会遍历整个堆,回收没有打上标记的对象(即垃圾)。
    • 内存的合并操作也是在清除阶段进行的。
  3. 分配

    • 分配指将回收的内存空间进行再利用。
    -> 伪代码实现内存分配
    
    new_obj(size){
        chunk = pickup_chunk(size, $free_list)
        if(chunk != NULL)
            return chunk
        else
            allocation_fail() //大招,销毁并释放全部空间
    }

优点

  1. 实现简单
  2. 与保守式GC算法兼容

缺点

  1. 碎片化(fragmentation)

    • 使用过程中会逐渐产生被细化的分块
  2. 分配速度

    • 分块不连续,每次分配都必须遍历空闲链表,以便找到足够大的分块。
    • 最糟的情况就是每次分配都要遍历全部空闲链表
  3. 与写时复制技术(copy-on-write)不兼容


为了解决分配速度的问题, 人们提出了两种方法

  • 使用多个空闲链表(multiple free-list)

    • 类似于建立索引的方法。
    • 为了防止空闲链表(也就是索引)的数组过大的问题,通常会给分块大小设定一个上限。
    • 大于这个上限的按照一个空闲链表处理。

      • ex.
      • 设置上限为100
      • 那么准备1~100及大于等于101个字的100个空闲链表就可以了。
    -> 伪代码实现使用多个空闲链表的内存分配
    
    new_obj(size){
        index = size / (WORD_LENGTH / BYTE_LENGTH)
        if(index <= 100)
            if($free_list[index] != NULL)
                chunk = $free_list[index]
                return chunk
        else
            chunk = pickup_chunk(size, $free_list[101])
            if(chunk != NULL)
                return chunk
    
        allocation_fail() //大招,销毁并释放全部空间
    }
  • BiBOP(Big Bag Of Pages)法

GC标记-清除算法(Mark Sweep GC)

标签:两种   优先   利用   碎片   page   设定   建立   速度   情况   

原文地址:https://www.cnblogs.com/leisurelylicht/p/GC-biao-jiqing-chu-suan-fa-Mark-Sweep-GC.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!