Setting the keys of a dictionary table to a part and then setting those keys to nil does not garbage collect or the Performance tab does not update accordingly
The code:
The Performance tab in action:
Expected behavior
The PhysicsPart memory category should go back down to the same level as it was, after the parts are destroyed and references are nilled out.
I believe you’re still holding a reference to the original BasePart by using it as a table key. If you set the entire ListOfParts to {}, does the memory get correctly GC’ed?
You can see at line 17 all the keys within the table are set to nil. I have tried multiple combinations including the one you suggested and still the memory persists in the performance tab.
When I check the graph after the following code runs:
local Lighting = game:GetService("Lighting")
task.wait(6)
print("Started")
local ListOfParts = {}
for _ = 1, 250 do
for _ = 1, 100 do
local BasePart = Instance.new("Part")
BasePart.Parent = Lighting
ListOfParts[BasePart] = {"data", true}
end
task.wait()
end
print(`Rem in 5 seconds`)
task.wait(5)
warn(`Removing...`)
Lighting:ClearAllChildren()
for BasePart, Data in ListOfParts do
ListOfParts[BasePart] = nil
end
--ListOfParts = {}
print(`Done.`)
It first rises to 50 MBs, before then dropping to 1.7 after 5 seconds. Are you sure you just didn’t wait long enough for the system to figure out it can get rid of the parts?
:Destroy removes a part from memory as long as there are no remaining “references” to it, it’ll also disconnect any script connections to the part, such as .Touched.
EDIT: Hmm, the memory leak seems to only happen if run from the Command Bar in Edit mode. It even persists between Play Tests!
Garbage collection does not necessarily happen immediately. It can happen at arbitrary times in the future. Other studio systems/plugins can hold references to the Parts too.
This is expected behavior, will close this ticket.