Lua GC 机制

垃圾回收

Lua 垃圾是自动回收的,但是也提供了 API 用于手动控制回收时机,在合适的时候手动调用 GC,较为平缓的控制内存占用。

调用 collectgarbage([opt [, art]]) 控制 GC,opt有

注:”setpause” 和 “setsetpmul” 共同控制着 GC 频率

示例

local function Func( )
    local a = {}
    for i = 1, 1000 do
        table.insert(a, i)
    end
end

collectgarbage("collect")

collectgarbage("setstepmul", 200)
print("count-size : " .. collectgarbage("count"))
local previous = collectgarbage("setpause", 200)

print("begin")
for i = 1, 8 do
    Func()
    print("count-size ".. i .." : " .. collectgarbage("count"))
end
print("end")

print("count-size : " .. collectgarbage("count"))

输出

count-size : 20.3857421875
begin
count-size 1 : 37.1953125
count-size 2 : 53.3115234375
count-size 3 : 69.43359375
count-size 4 : 37.009765625
count-size 5 : 53.1298828125
count-size 6 : 69.251953125
count-size 7 : 37.0107421875
count-size 8 : 53.1328125
end
count-size : 53.2177734375

可以初始有用到的内存大致占用 20kb,并从增长速率可以看出,每次 Func() 循环会产出 16kb 左右 garbage。设置collectgarbage("setpause", 200)后,根据说明,应该在 40kb 的时候触发一次 GC,但是似乎 GC 并没有很符合预期。在 53kb 后,再次提升为 69kb。第二次的循环就会让内存占用超过到 40kb,没有进行 GC 可以理解为申请内存时先判断是否超过设定值,37kb 时没有超过,所以又一次申请了 16kb 内存。但为什么还会出现 69kb 的情况呢,原因就在collectgargage("setstepmul", 200)上,200 速度太低了。当设置为 900 后,可获得

count-size : 20.4013671875
begin
count-size 1 : 37.2109375
count-size 2 : 53.3271484375
count-size 3 : 37.02734375
count-size 4 : 53.1455078125
count-size 5 : 37.02734375
count-size 6 : 53.1455078125
count-size 7 : 37.02734375
count-size 8 : 53.1455078125
end
count-size : 20.99609375

Get~