Will this be garbage collected?

Lets say I have a table local tbl = {}, and lets say that in that table we stored a part table.insert(tbl, workspace.Part). If the server destroyed that part workspace.Part:Destroy(), would it be good practice to remove the object from the table to prevent memory leaks table.remove(tbl, 1), or should we not remove it from the table, and instead let roblox garbage collect it?

I believe the table would return nil, wouldn’t it?

Cause the table holds a reference to the part.

Therefore, the only thing you need to worry about, is removing it from the list to avoid getting nil values

Destroy sends an object to garbage collection.

1 Like

But wouldn’t it also return nil if it is removed from the table?

If it’s not in the table, or the edit: game enviroment It’s nil.

1 Like

So either way its gonna be nil?

Yes. But if left in the table, it will mess it up if you’re storing and deleting objects. Best to just clean up the table.

It’ll mess up depending on how you’re using it. But for best practices, just clean it up with a custom event handler.

1 Like

Roblox will not collect a destroyed part until all references to it don’t exist anymore. This means that if the part is referenced directly or indirectly in any variable, it will stay in memory and will not be deleted.

Whenever you call :Destroy on any instance, all it does is parent the instance to nil, lock the .Parent property, and disconnect all event connections. It does not explicitly remove it from memory.


What counts as a reference?

dictionary[key] = Part
table.insert(array, index, Part)
variable = Part

You can destroy these references by making what is storing the part nil:

dictionary[key] = nil

table.remove(array, index)
-- OR
dictionary or array = nil

variable = nil

Keep in mind that you would have to do this for all references if the part is stored in multiple places.


If you’re using a local variable, the reference to the variable will be destroyed when they go out of scope:

do -- create a new scope

	local variable = Part -- make a reference to the part

end -- reference is destroyed, since it's now out of scope!

Functions use the variable itself as a reference and doesn’t save it there in the function:

local Part = -- your part

function fn()
	print(Part.BrickColor.Name)
end

fn() --> Medium stone grey

Part = nil

fn() --> errors

Connections to events are known to cause memory leaks, but it gets very technical:

Destroyed parts can still be referenced by variables in the meantime though, which means you can access their properties as well as methods and events but who cares about that:

Part:Destroy()

-- this is possible
local storedColor = Part.Color

Part = nil
5 Likes

So that block of code can be used to remove the reference in the table?

Yeah, but for arrays I would use table.remove. It will move all the other elements back one to keep the behavior of an array.

The dev hub has an article about what arrays are, and the other kinds of tables too: https://developer.roblox.com/en-us/articles/Table

1 Like

I have one question. If I have a table inside a table like local table = {anotherTable = {}}

How would I remove something in the “anotherTable” table? Would I use something like this: table.remove(table[1], 1)?

In that specific example, I would use table.remove(table.anotherTable, 1), since the anotherTable is stored in the key of the same name, but basically, yes.

You would also have to name the base table something different, just because table is already taken, e.g. local tabl = ...

1 Like

What about if the table inside the other table was created like so: Table[#Table + 1] = {Inst1, Inst2} How would I delete Inst1, and Inst2?

(Unless I am dumb, and that is not a table inside another table)

If you have access right after that line was made, you could just use table.remove(Table), and it will automatically remove the last element from Table, which is the instance array.

If you don’t, you can store an index of the new array and remove it using table.remove that way:

local index = #Table + 1
Table[index] = {Inst1, Inst2}

-- later,
table.remove(Table, index)
1 Like