在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
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 流程的启始步骤。只是标记系统的根节点。 (1)标记阶段:把根节点的集合(由lua语言可以直接访问的对象组成)标记为活跃状态,在lua语言中,这个集合值包括注册表, 保存在一个活跃对象中的对象是程序可达的,因此也会被标记为活跃(弱引用表中的内容除外)当所有可达对象都被标记为活跃后 标记阶段结束。 (2)清理阶段:首先,lua语言会遍历所有的被标记为需要进行析构,但是又没有被标记为活跃状态的对象。这些没有被标记为 活跃状态的对象会被标记为活跃(复苏),并且被放在一个单独的列表中,这个列表会在析构阶段用到,然后,lua语言遍历弱引用表 并从中移除键或值未被标记的元素。 (3)清除阶段:遍历所有的对象(lua会把所有创建的对象放在一个链表中),如果一个对象没有被标记为活跃状态,就将其回收, 否则,就清理标记,然后准备进入下一个清理周期。 (4)析构阶段:调用清理阶段被分离出来的对象的析构器(我的理解就是拿到清理阶段的列表,清理列表中的对象,列表只包含 真正需要清理的对象,那些在弱引用表中被标记的元素已经从列表中移除,也就是有 图解:
GC的api:(自动调用GC:当lua使用的内存到达阀值) (该api为手动调用GC) opt参数可以为:
参考:https://blog.csdn.net/BigBrick/article/details/85317491 https://blog.csdn.net/SamGeren/article/details/108066380
|
请发表评论