垃圾回收
Lua语言使用自动内存管理。通过垃圾收集自动删除成为垃圾的对象。
Lua中主要的辅助垃圾收集器的机制有:
- 弱引用表 (weak table)
- 析构器 (finalizer)
- 函数 collectgarbage
弱引用表允许Lua收集被程序访问的对象,但是数字和布尔不会被回收;
析构器允许收集不在垃圾收集器控制下的外部对象;
函数 collectgarbage 允许手动控制垃圾收集器的步长
弱引用表
一个表是否为弱引用表是由其元表中的 __mode控制。
如果该字段值为"k", 那么这个表的键为弱引用
如果该字段值为"v",那么这个表的值为弱引用
如果该字段值为"kv",那么这个表的键和值都为弱引用
__mode模式为 "k"
表示弱引用表的键为弱引用,当键被覆盖,可以被回收
local weaktable={
}
local metable ={
__mode ="k"
}
--这里tab就是返回的weaktable
local tab = setmetatable(weaktable,metable)
local table1={
}
weaktable[table1]=5
--当打开这里的注释后,需要给collectgarbage()方法添加上注释,会发现弱引用表里面的值被回收
-- for key, value in pairs(weaktable) do
-- print(key,value)
-- end
--将键置为nil,弱引用表中就会回收它
table1=nil
print("--------------")
collectgarbage()
for key, value in pairs(weaktable) do
print(key,value)
end
__mode 模式为"v"
表示弱引用表的值为弱引用,当值置nil,可以被回收
略微修改上面的案例:
local weaktable={
}
local metable ={
__mode ="v"
}
--这里tab就是返回的weaktable
local tab = setmetatable(weaktable,metable)
local table1={
}
weaktable[5]=table1
--当打开这里的注释后,需要给collectgarbage()方法添加上注释,会发现弱引用表里面的值被回收
-- 当然,是否被回收都不影响置为nil后,weaktable长度变成0
-- for key, value in pairs(weaktable) do
-- print(key,value)
-- end
table1 = nil
collectgarbage()
for key, value in pairs(weaktable) do
print(key,value)
end
__mode模式为"kv"
案例可参考上面的"k"和"v",作用就是上面作用的叠加,详细过程略。
总结
至于为什么键和值必须是引用类型(例如用表作为键或者值)才能让弱引用表的回收功能生效,为什么是数字类型或者布尔类型无法生效,值得深入研究,这里只写了结论,不再深究。
析构器
__gc元方法,对象释放时的操作,垃圾回收后占用内存变小
local ob={
"hello"}
local oj={
ob,}
local metable={
__gc=function (ob)
print("-------gc-------")
for key, value in pairs(ob) do
print(key,value)
end
print("----------------")
end
}
setmetatable(ob,metable)
ob=nil
-- 垃圾回收前
print(collectgarbage("count"))
-- 执行垃圾回收
collectgarbage()
-- 垃圾回收后
print(collectgarbage("count"))
--输出,可以看到占用内存变小了
25.1328125
24.1923828125
-------gc-------
1 hello
----------------
函数 collectgarbage
控制垃圾收集的步长。
通过collectgarbage对垃圾收集器进行一些特别的操作。
collect
强制进行垃圾回收,这个是默认值。例如:
collectgarbage("collect")
count
返回当前的Lua内存使用情况。例如:
local count = collectgarbage("count") print("Memory usage:", count, "KB")
stop
暂停垃圾回收器。例如:
collectgarbage("stop")
restart
重新启用垃圾回收器。例如:
collectgarbage("restart")
setpause
设置垃圾回收器的暂停比例。例如:
collectgarbage("setpause", 200)
setstepmul
设置垃圾回收器的运行速度相对于内存分配速度的倍数。例如:
collectgarbage("setstepmul", 1000)
step
设置step
参数为一个正整数表示垃圾回收器工作的步数,垃圾回收器将进行n
个步骤的工作
collectgarbage("step", n)
设置step
参数为一个负整数表示垃圾回收器工作直到回收所有未使用的内存,垃圾回收器将工作直到回收了至少n
字节的内存,或者无法再进行垃圾回收为止
collectgarbage("step", -n)
设置step
参数为0表示垃圾回收器不进行完整的垃圾回收过程,只以最小步长来执行。
collectgarbage("step", 0)