【Lua基础系列】垃圾回收机制

                          【Lua基础系列】垃圾回收机制

    

大家好,我是Lampard~~

欢迎来到Lua进阶系列的博客

前文再续,书接上一回。今天和大家讲解一下lua中的垃圾回收机制

 

在 Lua 中,一共只有8种数据类型,分别为 nil 、boolean 、userdata 、number 、string 、 table 、 function 、 userdata 和 thread 。其中,只有 string table function thread 四种是以引用方式共享,是需要被 GC 管理回收的对象。

Lua采用的是Mark-sweep算法:

mark阶段
这个阶段叫做扫描阶段。简单来讲,就是对于现在lua用到的所有对象进行扫描一次。如果某个对象当前跟别的对象有引用关系,那么说明他还在用;如果某个对象跟其他任何对象都没有引用关系了,说明这个对象已经没有用了。这个阶段做完,就可以知道哪些对象还有用,哪些对象不再使用了,下面就交给下一个阶段,sweep阶段。
cleaning阶段

这个阶段lua会出里对象的析构和弱引用表,它会遍历标记需要析构的对象,以及遍历弱引用表将要移除的键或者值

sweep阶段
这个阶段做的事情其实很少,关键步骤在前一个阶段做完了。这个阶段根据前一个扫描阶段得到的结果,遍历一遍所有对象。如果这个对象已经标记为不再使用了,就会被清理掉,释放掉所在的内存;如果这个对象还在使用,那么就处理一下状态,等待下一次gc在处理。

finalization析构

对标记需要析构的对象进行析构

这里添加一下对弱表的介绍:若一个存放在表中,那么哪怕这个对象没有被任何地方引用,但是也不会被清除,因为此时这个对象就正在被这个表引用。为了解决这个问题可以在表中的__mode字段来定义该表是一个弱表,那么在GC的时候才会把它给回收掉

__mode = "k"  -- 代表这个表中的键是弱引用的弱引用表

__mode = “v”  -- 代表这个表中的值是弱引用的弱引用表

__mode = “kv” -- 代表这个表中的键值都是弱引用的弱引用表

无论哪一种情况,只要其中一个键或者值被回收了,那么整个键值对就会被回收,这和我们把变量置位nil其实是将它 删除的原理是一样的

 

缺陷:

在lua5.0之前,早期的 Lua GC 采用的是 stop the world 的实现。一旦发生 gc 就需要等待整个 gc 流程走完。(STW: 在垃圾回收期间除了垃圾回收器线程,其他线程都会被挂起)

如果mark阶段一次性把所有节点都扫描,再一次性清理完,那么这两个步骤就都很简单了。但是,这样就有效率问题,一次性要把所有对象处理一遍,在大工程里面就绝对是一个瓶颈。

所以,lua5.0以后就把gc改成了增量式的gc,主要是把标记扩展成了三种颜色,下面详细介绍一下。

我们可以将所有对象分成三个状态:
White状态,也就是待访问状态。表示对象还没有被垃圾回收的标记过程访问到。
Gray状态,也就是待扫描状态。表示对象已经被垃圾回收访问到了,但是对象本身对于其他对象的引用还没有进行遍历访问。
Black状态,也就是已扫描状态。表示对象已经被访问到了,并且也已经遍历了对象本身对其他对象的引用。

将root集合引用到的对象从White设置成Gray,并放到Gray集合中;

while(Gray集合不为空,并且没有超过本次计算量的上限)
{
    从Gray集合中移除一个对象O,并将O设置成Black状态;
    for(O中每一个引用到的对象O1) {
        if(O1在White状态) {
            将O1从White设置成Gray,并放到到Gray集合中;
        }
     }
}
for(任意一个对象O){
    if(O在White状态)
        销毁对象O;
    else
        将O设置成White状态;
}

但是由于垃圾回收的过程变成分步的话,那么我们之前已经标注到的状态就可能会发生改变,此时lua提供了屏障barrier在程序正常运行过程中,监控所有的引用改变,然后更换对象的状态。

 

好,今天的分享就到这里,祝各位功力渐长平步青云,谢谢大家~~

 

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lampard杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值