Lua GC【纯学习理解+总结,不涉及源码】

Lua GC【纯学习理解+总结,不涉及源码】

采用算法

MarkSweep算法

MarkSweep

扫描整个Heap内存的对象,对象如果存在引用,其相关引用就可以标记未可到达对象,剩下的碎片对象标记为不可到达对象,然后执行sweep操作回收不可到达对象。

不好理解?请类比想像一下树与树外的分散节点的关系

Lua的MarkSweep

  • 5.0版本以前----双色标记法
  • 5.1版本以后----三色标记法

5.0版本以前的双色标记法

简述:一个对象要么被引用,要么没被引用,非黑即白,直接扫一边回收没有引用的对象。

缺点:不可中断
缺点原因:双色标记法中,如果在GC的过程中加入新对象,这时候新加入的对象无论怎么设置都会带来问题,如果设置为白色,则如果处于回收阶段,则该对象会在没有遍历其关联对象的情况下被回收(新设置的未被使用就直接回收,不可);如果标记为黑色,那么没有被扫描就被标记为不可回收,是不正确的(没有经过扫描检验直接判定黑色,你可以理解为办案中没收集证据侦察环节就直接判一个人死刑,这铁定不行)。
缺点影响:每次触发GC都要一次做完,并且每次GC触发条件是内存分配到达了上次GC两倍,这种设计直接导致跑GC越跑越慢,最后执行速度上不可接受。

5.1版本以后的三色标记法

三色标记法解决了GC过程不可中断的问题,GC过程可以分步执行,增量回收,被中断之后可以继续执行

三色
  • 白色:新建对象的初始状态。如果在一轮GC扫描结束后,对象还是为白色,该对象可以被进行回收了。
  • 灰色:表示对象已经被GC扫描过,但该对象引用的对象还没被扫描到。
  • 黑色:表示对象已经被GC扫描过,同时该对象引用的对象也被扫描过了。

个人理解(说点人话)

  • 白色状态表示该对象没有任何引用,定义为程序的碎片垃圾,需要回收;
  • 灰色表示正在进行却没有完成的扫描状态,这里是5.1后优化的点,这种设计决定了5.1后的GC是可以被中断的;
  • 黑色表示这个资源已经扫描完毕,此时已经构建出一整个程序正在使用的黑色资源树,是当前程序运行的必要资源,不可以回收。

流程伪代码如下

三色标记流程伪代码
--伪代码描述

-- 白色:新建对象的初始态。如果在一轮GC扫描结束后,对象还是为白色,该对象可以被进行回收了。
-- 灰色:对象已经被GC扫描,但未扫描到其相关引用。
-- 黑色:对象已经被GC扫描,已经扫描过其相关引用。

------------------------------------------------------------------------
--上下文阶段
上下文代码执行
上下文创建了新对象,新对象被设置为 <白色>

-------------------------------------------------------------------------
--程序运行中时,GC启动

--初始化阶段
遍历root节点中的引用对象,将白色对象设置为灰色对象,并且放入灰色节点链表中

--检查标记阶段
while 灰色链表节点不为空
do
    从链表当中取出一个对象,设置为黑色(标志着该对象已经被扫描)
    遍历这个黑色对象的所有相关引用对象:
    if 相关引用对象的颜色为白色 then
        相关引用对象塞进灰色节点链表当中
end

--回收阶段

遍历所有对象:

if 对象为白色 then
    该对象没有被引用,执行回收
else
    重新塞入到对象链表当中等待下一轮GC
end
--一轮GC结束
----------------------------------------------------------------------

本文学习链接1:Lua中的GC垃圾回收机制
本文学习链接2:【Lua基础系列】垃圾回收机制
源码分析连接:Lua源码分析之垃圾回收

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值