How do I make value in a weak table get garbage collected correctly?

I’m trying to make the values in a key-value table be garbage collected by using __mode = “v”. However, it doesn’t work at all! What am I doing wrong?

local myOtherTable = {} -- This is used as an example key/value. It doesn't have any special meaning beyond that
local myOtherTable2 = {} -- Same as above
local myTable = {[myOtherTable] = 123, [123] = myOtherTable2, ControlKey = "ControlValue"} -- A strong reference to myTable which is a table that contains some keys and values

myOtherTable = nil -- Make sure we remove the reference to the other table! Our script reference counts as a strong reference.
myOtherTable2 = nil -- Same as above

setmetatable(myTable, {__mode = "v"}) -- Make the table values weak references

-- The code below will loop through the table. Notice that all keys and values we set when creating the table show up even after __mode has been changed. This is because the garbage collector hasn't run yet.
for key, value in pairs(myTable) do -- Loop through the table
	print(key, "=", value) -- Print the contents of the table
end

delay(1.5, function() -- Allow time for the garbage collector to cleanup the script thread
	for key, value in pairs(myTable) do -- Loop through the table
		print(key, "=", value) -- Print the contents of the table
	end
	-- Notice that the key referencing the table didn't show up this time! This is because the garbage collector cleaned up our script. Try changing k to v and notice how the result now includes the key but not the value!
	-- Also notice how primitives like "ControlValue" weren't garbage collected. The parent thread controls references to these and any scripts which contain a copy of a string will prevent it from being garbage collection. Numbers are not garbage collected at all.
end)

image initial values before GC cycle

image values after GC cycle. “123 = {}” is supposed to be removed because of Line 6 in the script, but it isn’t. Am I misunderstanding something?

Uhm thats weird , I tried it and it worked fine for me image

As you can see the second time the Key 123 doesn’t exist.

EDIT : Also just noticed something , in your screenshot I see no change in time . As you can see in my screenshot the first print is at 39.786 and then at 42.178 but yours both of them are at 07.095

2 Likes

@Razor_IB has a good point about the time stamps. delay is unreliable, maybe it didn’t actually cause a delay for some reason.

But also, there’s no guarantee that the garbage collector will run in those 1.5 seconds, and we don’t really have control over it.

2 Likes