Lua 的垃圾回收机制是自动内存管理的一部分,用于回收不再使用的内存资源。Lua 使用 增量式垃圾回收器(Incremental Garbage Collector),这种机制可以有效减少程序暂停时间,从而提高运行效率。
在本指南中,我们将深入了解 Lua 的垃圾回收原理、如何手动控制垃圾回收、垃圾回收的优化技巧,以及实际应用中的注意事项。
1. Lua 垃圾回收的基本概念
1.1 什么是垃圾回收?
垃圾回收是自动化的内存管理机制,用于释放不再使用的内存资源。在 Lua 中,垃圾回收的主要目标是:
- 清理孤立或不可达的对象(如表、函数、协程等)。
- 避免内存泄漏,确保程序运行时内存不会无限增长。
1.2 Lua 的垃圾回收原理
Lua 使用 标记-清除算法(Mark-and-Sweep) 作为垃圾回收的基础,并通过增量式方式优化性能。
垃圾回收的主要步骤:
- 标记阶段:
- 垃圾回收器会遍历所有可达对象(从根对象开始,如全局变量、栈变量等)。
- 将所有可达对象标记为“存活”状态。
- 清除阶段:
- 未被标记为“存活”的对象将被认为是垃圾,释放它们占用的内存。
增量式垃圾回收:
Lua 将垃圾回收过程分解为多个小步骤,每次只执行一部分工作,从而避免程序长时间暂停。
1.3 垃圾回收触发条件
垃圾回收器会在以下情况下触发:
- Lua 分配了足够多的新内存(超过上次垃圾回收后分配的阈值)。
- 使用
collectgarbage
手动触发。
2. 手动控制垃圾回收
Lua 提供了 collectgarbage
函数,用于查询和控制垃圾回收器。
2.1 collectgarbage
函数
语法
collectgarbage([opt [, arg]])
opt
:指定操作类型(如启动回收、设置参数等)。arg
:可选参数,用于调整垃圾回收器的行为。
常见操作
操作 (opt ) |
描述 |
---|---|
"collect" |
立即执行完整的垃圾回收。 |
"stop" |
停止垃圾回收器。 |
"restart" |
重启垃圾回收器。 |
"count" |
返回当前 Lua 使用的内存量(以 KB 为单位)。 |
"step" |
执行垃圾回收的一小步,返回是否完成。 |
"setpause" |
设置垃圾回收的触发阈值(默认值 200)。 |
"setstepmul" |
设置垃圾回收的步进倍率(默认值 200)。 |
2.2 示例:手动垃圾回收
示例 1:强制回收
local t = {}
for i = 1, 1e6 do
t[i] = i
end
print("Before GC:", collectgarbage("count"), "KB") -- 查看内存使用量
t = nil -- 删除引用
collectgarbage("collect") -- 强制回收
print("After GC:", collectgarbage("count"), "KB") -- 再次查看内存使用量
示例 2:分步垃圾回收
local t = {}
for i = 1, 1e6 do
t[i] = i
end
t = nil -- 删除引用
while not collectgarbage("step", 100) do
print("Performing incremental GC...")
end