美文网首页
GC-引用计数法

GC-引用计数法

作者: 夜莺纪事 | 来源:发表于2018-12-31 21:42 被阅读0次

    引用计数的算法

    • 计数器:对象的被引用数(多少程序引用过这个对象)
    • 计数器值增减
      引用计数法中没有明确启动GC的语句。在mutator的处理过程中通过增减计数器的值来进行内存管理。
      涉及计数器增减的情况 - new_obj()和update_ptr()
    • 创建对象
      引用计数法中,除了free_list中的对象,其余都是活动对象。如果pick_chunk()失败,堆中就没有合适的分块了;如果成功,将该对象计数器置1,说明对象已生成且被引用。
    • 指针更新
      1. reclaim()将obj链接到空闲链表
      2. 先调用inc再调用dec,以处理更新前后指针指向的是同一对象的情况。如果先调用dec,可能导致对象被引用数为0,继续调用inc时所需对象已被回收。
    • 引用计数法特征:mutator和内存管理同时运行。

    优点

    • 可即刻回收垃圾
      内存不会被垃圾占用,其他GC算法中直到GC开始执行之前,都有一部分内存被垃圾占用(分块用尽后才会执行GC)。
    • 最大暂停时间短
    • 不必沿指针查找
      相对适用于分布式环境。
      一种做法是各个计算节点内回收垃圾使用GC标记-清除算法,考虑节点间引用关系用引用计数法。

    缺点

    • 计数器增减处理繁重
      指针频繁更新导致计数器频繁更新。
    • 计数器占位很多
      用于引用计数的计数器最大必须能数完堆中所有对象的引用数。
    • 实现复杂
    • 循环引用无法回收
      两个或两个以上对象互相循环引用,使计数器都无法清零,即使该对象组都成了垃圾,也无法被程序回收。

    延迟引用计数法

    • 是什么
      使从根引用的指针变化不反映在计数器。
      使用ZCT(Zero Count Table),记录调用dec之后计数器值为0的对象(可能是垃圾,也可能不是)。
    • 修改dec函数和内存分配函数
    • scan_zct()
      zct满的时候调用,内存没有合适的分块用于分配时调用。
    scan_zct(){
        for (r : $root)
          (*r).ref_cnt++
    
        for(obj : $zct)
          if (obj.ref_cnt == 0)
            remove($zct, obj) //remove obj from zct 
            delete(obj) //1. 对子对象计数器做--;2. 回收
      
        for (r : $root)
          (*r).ref_cnt--
    
    • 优点
      减轻指针引用频繁修改导致的计数器增减所带来的负担。
    • 缺点
      不支持立刻回收垃圾
      scan_zct()导致最大暂停时间变长

    Sticky引用计数法

    1位引用计数法

    部分标记-清除算法

    相关文章

      网友评论

          本文标题:GC-引用计数法

          本文链接:https://www.haomeiwen.com/subject/yyxilqtx.html