垃圾收集
Lua 语言使用自动管理。程序可以创建对象(表、闭包等),但却没有函数来删除对象。Lua 语言通过垃圾收集自动地删除成为垃圾的对象,从而将程序员从内存管理的绝大部分负担中解放出来。同时对于无效指针(dangling pointer) 和内存泄漏(memory leak) 等问题。
弱引用表(weak table)、析构器( finalizer) 和函数 collectgarbage 是在 Lua 语言中用来辅助垃圾收集器的主要机制。若引用表允许收集 Lua 语言中还可以被程序访问的对象; 析构器允许收集不在垃圾收集器直接控制下的外部对象;函数 collectgarbage 则允许我们控制垃圾收集器的步长。
弱引用表
垃圾收集器不能猜测我们认为哪些是垃圾。一个典型的例子就是栈。栈通常由一个数组合一个指向栈顶的索引实现。我们知道,数组的有效部分总是向顶部扩展的, 但 Lua 语言却不知道。 如果弹出一个元素时只是简单地递减顶部索引,那么这个仍然留在数组中的对象对于 Lua 语言来说并不是垃圾。同理,即使是程序不再会用到的,存储在全局变量中的对象,对于 Lua 来说也不是垃圾。在这两种情况下都需要我们显示地将这些对象所在的位置赋值为 nil。
不过,简单地清除引用还不够,在有些情况下,还需要程序和垃圾收集器之间的协作。比如,当我们要保存某种类型(如文件)的活跃对象列表时。这个需求看上去简单,我们只需要将每个新对象插入数组即可。但是,一旦一个对象成为了数组的一部分,它就再也无法被回收了。虽然已经没有其他地方在引用它,但数组依然在引用它。除非我们告诉 Lua 语言对该对象的引用不应该阻碍对此对象的回收,不然 Lua 语言是无从知晓的。
弱引用表就是这样一种用来告诉Lua 语言一个引用不应组织对一个对象回收的机制。所谓弱引用,是一种不在垃圾收集器考虑范围内的对象引用。如果对一个对象的所有引用都是弱引用,那么垃圾收集器将会回收这个对象并删除这些弱引用。 Lua 语言通过弱引用表来实现弱引用,弱引用表就是元素均为弱引用的表,这意味着如果一个对象只被一个弱引用表持有,那么Lua 语言就会回收该对象。