解析Lua中的GC

Lua回收算法的原理:

不同的语言,对GC算法的设计不同,常见的GC算法是引用计数和Mark-Sweep算法, c#采用的是Mark-sweep && compact算法

Lua采用的是Mark-sweep算法,分开说一下:

引用计数算法:在一个对象被引用的情况下,将其引用计数加1,反之则减1,如果计数值为0,则在GC的时候回收,这个算法有个

问题就是循环引用。

Mark-sweep算法(标记清除法):

标记:每次执行GC时,先以若干根节点开始,逐个把直接或间接和它们相关的节点都做上标记;

清除:当标记完成后,遍历整个对象链表,把被标记为需要删除的节点一一删除即可。

Lua垃圾回收有三种颜色:

白色:可回收状态。(分为白1,白2)

      如果该对象未被GC标记过则此时白色代表当前对象为待访问状态。举例:新创建的对象的初始状态就应该被设定为白色,因

为该对象还没有被GC标记到,所以保持初始状态颜色不变,仍然为白色。如果该对象在GC标记阶段结束后,仍然为白色则此时

白色代表当前对象为可回收状态。但其实本质上白色的设定就是为了标识可回收。

灰色:中间状态。

      当前对象为待标记状态。举例:当前对象已经被GC访问过,但是该对象引用的其他对象还没有被标记。

黑色:不可回收状态。

      当前对象为已标记状态。举例:当前对象已经被GC访问过,并且对象引用的其他对象也被标记了。

着色图:

 

Lua回收的四个阶段:

#define GCSpause 0 每个 GC 流程的启始步骤。只是标记系统的根节点。
#define GCSpropagate 1
#define GCSsweepstring 2
#define GCSsweep 3
#define GCSfinalize 4

(1)标记阶段:把根节点的集合(由lua语言可以直接访问的对象组成)标记为活跃状态,在lua语言中,这个集合值包括注册表,

保存在一个活跃对象中的对象是程序可达的,因此也会被标记为活跃(弱引用表中的内容除外)当所有可达对象都被标记为活跃后

标记阶段结束。

(2)清理阶段:首先,lua语言会遍历所有的被标记为需要进行析构,但是又没有被标记为活跃状态的对象。这些没有被标记为

活跃状态的对象会被标记为活跃(复苏),并且被放在一个单独的列表中,这个列表会在析构阶段用到,然后,lua语言遍历弱引用表

并从中移除键或值未被标记的元素。

(3)清除阶段:遍历所有的对象(lua会把所有创建的对象放在一个链表中),如果一个对象没有被标记为活跃状态,就将其回收,

否则,就清理标记,然后准备进入下一个清理周期。

(4)析构阶段:调用清理阶段被分离出来的对象的析构器(我的理解就是拿到清理阶段的列表,清理列表中的对象,列表只包含

真正需要清理的对象,那些在弱引用表中被标记的元素已经从列表中移除,也就是有__gc 方法的对象)。

图解:

 

GC的api:

(自动调用GC:当lua使用的内存到达阀值)

(该api为手动调用GC)

opt参数可以为:

  • “collect”:执行一个完整的垃圾回收周期,这是一个默认的选项
  • “stop”:停止垃圾收集器(如果它在运行),实现方式其实就是将gc.threshold设置为一个巨大的值,不再触发gc step操作
  • “restart”:将重新启动垃圾收集器(如果它已经停止)。
  • “count”:返回当前使用的的程序内存量(单位是Kbytes),返回gc->total/1024
  • “step”:执行垃圾回收的步骤,这个步骤的大小由参数arg(较大的数值意味着较多的步骤),如果这一步完成了一个回收周期则函数返回true。
  • “setpause”:设置回收器的暂停参数,并返回原来的暂停数值。该值是一个百分比,影响gc.threshold的大小,即影响触发下一次gc的时间,设置代码如下:

    g->gc.threshold = (g->gc.estimate/100) * g->gc.pause;

    g->gc.estimate为当前实际使用的内存的大小,如果gc.pause为200,则该段代码表示,设置gc的阈值为当前实际使用内存的2倍

  • “setstepmul”:设置回收器的步进乘数,并返回原值。该值代表每次自动step的步长倍率,影响每次gc step的速率,具体这么影响可以查看后面小节

参考:https://blog.csdn.net/BigBrick/article/details/85317491

            https://blog.csdn.net/SamGeren/article/details/108066380

 

 

 

 

 

 

 

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值