【问题标题】:Is it possible to deadlock memory in Lua like this?有可能像这样在 Lua 中死锁内存吗?
【发布时间】:2021-09-25 19:25:37
【问题描述】:
这两个表都相互引用,但在函数之外的任何其他地方都没有引用。这些表在调用 f() 后会保留在内存中还是会被垃圾回收?
function f()
local t1 = {}
local t2 = {}
t1[1] = t2
t2[1] = t1
end
f()
【问题讨论】:
标签:
memory
memory-management
memory-leaks
lua
deadlock
【解决方案1】:
这两个表将被垃圾回收。
t1 和 t2 是 f 范围的本地。一旦它们超出范围,t1[1] 和 t2[1] 将不再存在。
没有更多对剩下的两个表的引用,因此它们有资格进行垃圾回收。
【解决方案2】:
Lua 的垃圾收集检查可达性而不是仅仅使用引用计数,因此循环引用不会阻止收集。下面是您的程序的修改版本来证明这一点:
function f()
local t1 = setmetatable({}, {__gc = function() print "Collected t1" end})
local t2 = setmetatable({}, {__gc = function() print "Collected t2" end})
t1[1] = t2
t2[1] = t1
end
f()
print "Before collectgarbage()"
collectgarbage()
print "After collectgarbage()"
我得到的结果:
Before collectgarbage()
Collected t2
Collected t1
After collectgarbage()
请注意,表上的 __gc 元方法是 Lua 5.2 的新方法。如果你想在旧版本的 Lua 上尝试这个演示,你需要使用 newproxy 或者获取一个用户数据来代替。