Can weak values in a table avoid memory leaks from lost table refs?

Hi all, so I know that it usually isn’t best practice to “clear” a table just by removing reference to it like so:

local t = { CFrame.new(), CFrame.new(), CFrame.new() }
t = { }

Because that wouldn’t free the memory the objects use in the table. and technically that’s not even clearing it since you create a reference to a new table
I know the old t will eventually be garbage collected, but from what I know, the object references it contained won’t be. So here is the question: would making the values weak avoid the memory leak?

For instance, how would this be better than the first example?

local t = { CFrame.new(), CFrame.new(), CFrame.new() }
setmetatable(t, { __mode = "v" })
t = { }

Once the previous t gets garbage collected, shouldn’t the memory leak not occur since the objects inside don’t have any more references? I see a drawback to this, but that isn’t an issue for me right now.

I do realize to properly clear a table you just traverse it setting the keys to nil like so:

for i = #t, 1, -1 do -- probably doesn't need reverse order but i prefer doing so
    t[i] = nil
end

-- generic for loop could be used for non-arrays but im using array for an example

And I am not looking for an alternative method because this is perfectly fine. Though I do have a circumstance where the table element amount might not be the same as the iterations used to traverse the table, and I do not feel like having to redundantly clear the table myself when I might not need to.

I’ve also read on a few topics in #help-and-feedback:scripting-support and even, Garbage Collection and Memory Leaks in Roblox - What you should know but none seem to answer this specific question.

1 Like

Everything gets garbage collected when it loses its references. When your old table loses its last reference, it itself doesn’t count as a reference, so everything it holds loses their reference too. There’s no need to do hacky weak table magic.

2 Likes

@Autterfly’s correct. You can run a test in-game and track the memory usage to visually see the results:

I ran tests that involved filling a table with a lot of CFrame values and either clearing the table by setting all the values to nil or removing the reference to the table by just setting the variable to an empty table – in both cases, the results, memory-wise, were the same (the objects were GC’ed / there were no memory leaks).

2 Likes