Lua - 垃圾回收



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

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

Lua 使用垃圾收集器,该收集器会不时运行以收集不再可从 Lua 程序访问的死对象。

所有对象(包括表、用户数据、函数、线程、字符串等)都受自动内存管理。Lua 使用增量标记和清除收集器,该收集器使用两个数字来控制其垃圾收集周期,即 **垃圾收集器暂停** 和 **垃圾收集器步长乘数**。这些值以百分比表示,值 100 通常在内部等于 1。

垃圾收集器暂停

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

垃圾收集器步长乘数

此步长乘数控制 Lua 程序中垃圾收集器相对于内存分配的速度。较大的步长值会导致垃圾收集器更积极,并且还会增加垃圾收集每个增量步骤的步长。小于 100 的值通常会导致垃圾收集器无法完成其周期,通常不建议这样做。默认值为 200,这意味着垃圾收集器的运行速度是内存分配速度的两倍。

垃圾收集器函数

作为开发人员,我们确实可以控制 Lua 中的自动内存管理。为此,我们有以下方法。

  • collectgarbage("collect") − 运行一个完整的垃圾收集周期。

  • collectgarbage("count") − 返回程序当前使用的内存量(以 KB 为单位)。

  • collectgarbage("restart") − 如果垃圾收集器已停止,则重新启动它。

  • collectgarbage("setpause") − 将作为第二个参数给出的值除以 100 设置为垃圾收集器暂停变量。其用途如上所述。

  • collectgarbage("setstepmul") − 将作为第二个参数给出的值除以 100 设置为垃圾步长乘数变量。其用途如上所述。

  • collectgarbage("step") − 运行一步垃圾收集。第二个参数越大,此步骤就越大。如果触发的步骤是垃圾收集周期的最后一步,则 collectgarbage 将返回 true。

  • collectgarbage("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 解释器也会在预定义时间段后自动在稍后阶段执行它们。

示例 - 步进/停止垃圾收集器

下面显示了一个使用垃圾收集器示例的简单示例。

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

print(collectgarbage("count"))

mytable = nil

print(collectgarbage("count"))

print(collectgarbage("step"))

print(collectgarbage("stop"))

运行上述程序时,我们将得到以下输出。请注意,此结果将因操作系统的类型以及 Lua 的自动内存管理功能的不同而有所不同。

21.0029296875
21.0322265625
false
0

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

广告