Lua程序设计(六十三)

本文介绍了Lua语言的垃圾收集机制,从标记-清楚式的垃圾收集器到增量式收集器,详细解析了每个阶段的工作原理,包括标记、清理、清除和析构阶段。Lua5.1引入的增量式收集器避免了全局暂停,而Lua5.2的紧急垃圾收集在内存分配失败时进行。

垃圾收集器

Lua5.0之前, Lua语言使用的都是一个简单的标记-清楚(mark-and-sweep)式垃圾收集器(Garbage Collector GC)。这种收集器又被称作“stop-the-world(全局暂停)式的收集器,意味着Lua语言会时不时地停止主程序的运行来执行一次完整的垃圾收集周期(garbage-collection style)。 每一个垃圾收集周期由四个阶段组成:标记( mark), 清理(cleaning),清除(sweep)和析构(finalization)。

标记阶段把根节点结合(root set)标记为活跃,根节点集合由Lua语言可以直接访问的对象组成。在Lua语言中,这个集合只包括C注册表。

保存在一个活跃对象中的对象是程序可达的,因此也会被标记为活跃(弱引用不遵循这个规则)。当所有可达对象都被标记为活跃时,标记阶段完成。

Lua先执行清理阶段,再开始清除阶段。在清理阶段中处理析构器和引用表。首先,Lua语言遍历所有被标记为需要进行析构,但有没有被标记为活跃状态的对象,这些没有被标记为活跃状态的对象会被标记为活跃(复苏),并被放在一个单独的列表中。这个列表将在析构阶段中被使用。然后,Lua语言遍历若引用表并从中移除键或值未被标记的元素。

清除阶段遍历所有对象(为了实现这种遍历,Lua语言把所有创建的对象放在一个链表中)。如果一个对象没有被标记为活跃,Lua语言就将其回收。否则,Lua语言清理标记,然后准备进行下一个清理周期。

最后,在析构阶段,Lua语言调用清理阶段被分离出来的对象的析构器。

使用真正的垃圾收集器意味着Lua语言能够处理对象引用之间的环。

Lua5.1使用了增量式垃圾收集器(incremental collector)。这种垃圾收集器像老版的垃圾收集器一样执行相同的步骤,但是不需要在垃圾收集器期间停止主程序的执行。相反,它与解释器一起交替运行。每当解释器分配了一定容量的内存时,垃圾收集器也执行一小步(这意味着,在垃圾收集器工作期间,解释器可能会改变一个对象的可达性。为了保证垃圾收集器的正确性,垃圾收集器中的有些操作具有发现危险改动和纠正所涉及对象标记的内存屏障[barrier]。

Lua5,2引入了紧急垃圾收集(emergency collection)。 当内存分配失败时,Lua语言会强制进行一次完整的垃圾收集,然后再次尝试分配。这些紧急情况可以发生在Lua语言进行内存分配的任意时刻。包括Lua语言处于不一致的代码执行状态时,因此,这些收集动作不能运行析构器。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值