tl;dr: I can’t tell if garbage collection is working or not, as I believe it doesn’t run at all in some cases
Hello fellow developers. For the past week or so I’ve been trying to script with memory safety in mind. Unfortunately, my development has come to a complete halt as I cannot figure out if what I’m doing actually makes sense.
For context, I’m developing a ranged weapon system and I want it’s logic to be implemented solely under ReplicatedStorage and ServerScriptService. I find the idea of copying the same script a bit icky. To make sure my weapons don’t get initialized multiple times, I have to record these instances somehow.
Now, you may ask, “Why don’t you just use AncestryChanged?” Because there’s the possibility of the weapons being parented to nil, then parented back under the DataModel later again. (If your game has an admin system on it, the ;refresh command will do exactly that.) .Destroying is still in development so that’s unreliable.
That leaves me with no choice but to record these weapon instances in a table with it’s __mode metamethod set to "k".
local initializedTools = setmetatable({}, { __mode = "k" }) -- weak keys
I still have no idea if this works, when I decided to use a debugger later on to check, I still found them visible in the Watch window. I checked to see if my code just sucks, I got it down to the most bare-bones version I could get, shown below:
local initializedTools : {[Instance] : boolean} = setmetatable({}, { __mode = "k" }) -- weak keys
initializedTools[Instance.new("Part")] = true
game:GetService("RunService"):BindToRenderStep("",0,function()end)
while task.wait(10) do
for i,_ in initializedTools do
print(i)
i:Destroy()
end
task.wait(5)
print("bump") -- ! inserted a breakpoint here !
end
I don’t know what to make of this, either garbage collection just doesn’t work, or my place is so efficient that garbage collection never runs a cycle during testing. I can’t force a garbage collection cycle either, Roblox does not provide any way to do that.
Note: Strangely enough, the only time I see this table actually get cleared is when I run ;re with Adonis admin commands while I have the tools listed in the metatable. Maybe there’s something complex there that “wakes” it up? I don’t know.
Edit: I have tested by taking weapons, dying, then taking weapons again, then dying again, to see if it would have any changes on the table over time. After several restarts it never got past a certain amount of instances. Maybe my intuition is right and garbage collection just runs whenever it feels the time is right. Still such a bummer that I can’t explicitly call it to clear that up. It would make testing a LOT easier.
