Is it possible to deadlock memory in Lua like this?

Viewed 68

Both of these tables have references to each other, but neither are referenced anywhere else outside of the function. Will these tables remain in memory after a call to f() or will they be garbage collected?

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

f()
2 Answers

The two tables will be garbage collected.

t1 and t2 are local to f's scope. Once they run out of scope t1[1] and t2[1] no longer exist.

There are no more references to the two tables left so they qualify for garbage collection.

Lua's garbage collection checks for reachability rather than just using reference counting, so circular references will not prevent collection. Here's a modified version of your program to demonstrate this:

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()"

The result I get:

Before collectgarbage()
Collected t2
Collected t1
After collectgarbage()

Note that the __gc metamethod on tables is new to Lua 5.2. If you want to try this demo on older versions of Lua, you'll need to make use of newproxy or otherwise acquire a userdata to use instead.

Related