How can I go about determining if an object has been successfully garbage collected within the studio environment and not on runtime? I tried printing gcinfo()
, but it returns a different number each time I print it. Any help is appreciated. Thanks!
To tell if an object has been garbage collected, you need to know if the object doesn’t exist anymore. Since gcinfo is the total kilobyte of dynamic memory used by Lua, you won’t be able to use it as it isn’t consistent or predictable with all the other objects getting created and garbage collected.
Though if you do have a reference of the object, you can do something like this:
local Table = setmetatable({YOUR_OBJECT, {}}, {__mode = "kv"}) -- Create a weak table with your object in it and another empty table. The empty table is for detecting a garbage collection cycle.
YOUR_OBJECT = nil -- Remove the reference to your object, make sure there are no other references in any script to this specific object. This will let the object get garbage collected.
while Table[2] do task.wait() end -- Wait for garbage collection cycle
task.wait(1) -- Wait a little more to make sure the cycle completes
if Table[1] then -- The object did not get garbage collected
warn("Object did not garbage collect")
end
This works because a weak table allows items inside of it to get garbage collected without keeping a reference to them. Since you know that the first element in the weak table has your object, you’ll know that it got garbage collected when the first element doesn’t exist anymore.
Thanks for the explanation! I’m not quite sure I understand how to apply this, however. Since I’m testing this with an object in workspace, how would I refer to it in the script without making a strong reference and still be able to nullify it? I tried the following, but it got stuck in a loop and never returned anything.
local Table = setmetatable({workspace.Part, {}}, {__mode = "kv"})
Table = setmetatable({{}, {}}, {__mode = "kv"})
while Table[2] do task.wait() end
task.wait(1)
if Table[1] then
warn("Object did not garbage collect")
else
warn("gc")
end
If the part exists in workspace, a reference is held. You have to destroy the part to let it garbage collect in this case. So you’d want to do something like this:
local Part = workspace.Part
local Table = setmetatable({Part, {}}, {__mode = "kv"})
Part:Destroy()
Part = nil
while Table[2] do task.wait() end
task.wait(1)
if Table[1] then
warn("Object did not garbage collect")
else
warn("gc")
end
Not sure why you redefined the table variable again, you only need to place it in the first table where it said YOUR_OBJECT.
Mostly because I never fully understood __mode
​:P
Oh yeah I should explain, __mode is a metamethod that changes the table to have weak references depending on the string you set it as. the “k” means the keys of the table will be weak references and the “v” means the values are weak. If you want to learn more you should check out:
Are there values other than k and v? The documentation doesn’t list any in its description.
Yeah there seems to be another option, “s”, which makes the table “shrinkable”. This resizes tables when their content is garbage collected. So if you make a table with 5 elements and those elements are garbage collected, the “internal” size that the table takes in should still be 5. “s” option for __mode will change the table to shrink after garbage collection depending on the amount of elements it has. The option is not a part of original Lua, only Luau.
Though this is not something you should worry about at all, it doesn’t seem to affect tables a lot for you to use it in the first place.
You can read about it here:
ctrl + f search “__mode” if you want to read the part about the “s” option.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.