是否可以像这样在 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()
这两个表将被垃圾回收。
t1
和 t2
在 f
的范围内是局部的。一旦它们 运行 超出范围 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
或以其他方式获取用户数据来使用。
这两个表都相互引用,但都没有在函数之外的任何其他地方引用。这些表在调用 f() 后会保留在内存中还是会被垃圾回收?
function f()
local t1 = {}
local t2 = {}
t1[1] = t2
t2[1] = t1
end
f()
这两个表将被垃圾回收。
t1
和 t2
在 f
的范围内是局部的。一旦它们 运行 超出范围 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
或以其他方式获取用户数据来使用。