|
The interaction of objects with finalizers and weak tables also has a subtlety. At each cycle, the collector clears the values in weak tables before calling the finalizers, but it clears the keys after it.
Here is a problem that I couldn't found any implementation about it in lua5.3.5 source code, Lua does nothing before/after calling the finalizers in c function GCTM (lgc.c).
In contrast, I found that in c function atomic (lgc.c), At each cycle, the collector clears the values in other weak tables before resurrecting all objects which has a finalizer, and the collector clears the keys after resurrecting these objects.
I wrote such lua code for verification:
do
local k = {}end
local tbl1 = setmetatable({ [k] = "Hello" }, { __mode = "k" })
local tbl2 = setmetatable({ Hi = k }, { __mode = "v" })
local tbl3 = setmetatable({ tbl1 = tbl1, tbl2 = tbl2, k = k }, { __gc = function(obj)
for k, v in pairs(obj.tbl1) do print("tbl1:", k, v) end --> print k => Hello
for k, v in pairs(obj.tbl2) do print("tbl2:", k, v) end --> print nothing
print("obj.k:", obj.k) --> print table k
end })
print("Start...")
k = nil
tbl3 = nil
collectgarbage()
for k, v in pairs(tbl1) do print("First GC tbl1:", k, v) end --> print k => Hello
for k, v in pairs(tbl2) do print("First GC tbl2:", k, v) end --> print nothing
collectgarbage()
for k, v in pairs(tbl1) do print("Second GC tbl1:", k, v) end --> print nothing
for k, v in pairs(tbl2) do print("Second GC tbl2:", k, v) end --> print nothing
print("END!")