Lua进阶教程(二)垃圾回收

182 阅读3分钟

Lua进阶教程(二)垃圾回收

hudson 译 原文

Lua使用自动内存管理,基于Lua内置的某些算法进行垃圾回收。自动内存管理的结果是,作为开发人员:

  • 无需担心为对象分配内存。
  • 不需要释放它们。不再需要时,将其设置为nil。

Lua使用一个不时运行的垃圾收集器,收集已经死亡的对象,这些对象已经无法从Lua程序访问。

所有对象,包括表、用户数据、函数、线程、字符串等,都受制于自动内存管理。 Lua使用增量标记和扫描收集器,使用两个数字来控制其垃圾收集周期,即垃圾收集器暂停和垃圾收集器步进倍数。这些值以百分比为单位,100的值通常在内部等于1。

垃圾收集器暂停

该参数用于控制垃圾收集器需要等待多长时间后,再次由Lua的自动内存管理调用。小于100意味着Lua不会等待下一个完整周期。 同样,较高值将导致垃圾收集器变慢且本质上不那么具有攻击性。 值为200,意味着收集器在开始新周期之前,需要等待使用中的总内存翻倍。 因此,根据应用程序的性质和速度,可能需要更改此值,以获得最佳性能。

垃圾收集器步进倍数

该数控制垃圾收集器相对于Lua程序中内存分配的相对速度。 更大的值将导致垃圾收集器更具侵略性,它还会增加垃圾收集的每个增量步骤的步骤大小。 低于100的值会使垃圾收集器完不成其循环,通常不受青睐。 默认值为200,这意味着垃圾收集器的运行速度是内存分配速度的两倍。

垃圾收集器函数

作为开发人员,有时确实需要对Lua中的自动内存管理有一些控制权。 为此,Lua提供了以下方法:

方法描述
collect运行一次完整的垃圾回收循环。
count返回程序当前使用的内存量,以千字节为单位。
restart如果垃圾收集器已经停止,则重新启动它。
setpause将第二个参数给定的值除以100设置为垃圾收集器的暂停变量。
setstepmul将第二个参数给定的值除以100设置为垃圾步进乘数变量。
step运行一步垃圾回收。第二个参数越大,此步骤将越大。如果触发的步骤是垃圾收集周期的最后一步,则collectgarbage将返回true。
stop如果运行中,则停止垃圾收集器。

一个使用垃圾收集器的简单示例如下所示:

mytable = {"apple", "orange", "banana"}

print(collectgarbage("count"))

mytable = nil

print(collectgarbage("count"))

print(collectgarbage("collect"))

print(collectgarbage("count"))

运行上述程序时,将得到以下输出。请注意,由于操作系统类型的不同以及Lua的自动内存管理特性,输出结果可能会有所不同:

23.1455078125   149
23.2880859375   295
0
22.37109375     380

可以看到,在上面的程序中,一旦进行了垃圾收集,内存使用量就会减少。但是,不一定要调用它们。即使不调用它们,经过预定义的周期 后,Lua解释器也会在稍后的阶段自动执行它们。

显然,如果需要的话,可以使用这些函数来更改垃圾收集器的行为,为开发人员处理复杂情况提供了一些额外的能力。根据程序所需的内存类型,可能会或可能不会使用此功能。但是,了解应用程序中的内存使用情况并在编程过程中进行检查是非常有用的,可以避免在部署后出现不希望的结果。