是否可以像这样在 Lua 中死锁内存?

Is it possible to deadlock memory in Lua like this?

这两个表都相互引用,但都没有在函数之外的任何其他地方引用。这些表在调用 f() 后会保留在内存中还是会被垃圾回收?

function f()
     local t1 = {}
     local t2 = {}
     t1[1] = t2
     t2[1] = t1
end

f()

这两个表将被垃圾回收。

t1t2f 的范围内是局部的。一旦它们 运行 超出范围 t1[1]t2[1] 就不再存在。

剩下的两个表不再有引用,因此它们符合垃圾回收条件。

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 或以其他方式获取用户数据来使用。