Garbage Collection in short -
Garbage collection is Lua cleaning up references that aren’t needed anymore. If you have a function and your function contains local variables, when the function returns, those local variables are no longer needed and garbage collection clears them out of the machine’s memory.
function doStuff()
local tempReference = {}
tempReference[ 1 ] = 'hello'
tempReference[ 2 ] = 'world'
end
doStuff()
-- After running the function, the memory occupied
-- by the table referenced by tempReference will be
-- garbage collected next time the collector comes around.
If a strong reference is held to something, it will not be garbage collected. So for example, if your function creates a new table, and then sets a non-local or global variable to that table, a reference to the table has been created and it will now not be garbage collected when the function returns.
local variableOutside = nil
function doStuff()
local tempReference = {}
tempReference[ 1 ] = 'hello'
tempReference[ 2 ] = 'world'
variableOutside = tempReference
end
doStuff()
-- Now, the table created will not be removed from
-- memory. It will stay there for as long as this script exists.
Memory Leaks
Now, this can be a problem, because creating a connection, e.g. Part.Touched:Connect( anyFunction )
will create a connection that does not get garbage collected unless:
- a) the part is
:Destroy()
ed.
- b) you manually :Disconnect() the connection, and remove any references to it.
Memory leaks occur when the machine runs out of memory due to it being unable to garbage collect quicker than new references are being created, so if you kept creating event connections that were never properly removed. It can slow down your game or even crash it, and can sometimes lead to information that is trying to be stored in memory being leaked.
Maid Classes fighting memory leak
Maid classes help to organise connections and temporary things by keeping them all in a nice container. Once you’re done with it, the maid will clean up for you, ensuring everything is available for garbage collection.
I have no real experience using the actual Maid class source that a lot of people refer to, but I do often create my own lite version of this. Always disconnect connections you don’t need, and never hold reference to things in tables or anything else that you don’t need.
OOP examples
A common one is when people are using object-oriented programming and they create a new entity with a metatable stored in a table for every NPC for example, but when the NPC dies, they don’t remove the data from the table. As more and more spawn, the table grows and grows, and everything it references is not garbage collected. This will lead to a memory leak. If you used a Maid, you’d tell the maid to clean up when the NPC dies.
Weak Tables to the rescue
And finally, weak tables. In the example just given, a weak table would be ideal. You’d create a weak table, then set the NPC model as the key in the table for any data you want to keep about it, and when the NPC is removed from memory, the weak key/reference to it will be garbage collected with the associated values. You must keep a strong reference to the NPC in this case for as long as you need the associated values to remain in the table for, as it will be removed from memory when there are no strong references to it anymore. Keys in tables are strong by default, so if you just set an object as a key, you will have created a strong reference and even after the object is seemingly deleted, the data in the table is still being held in memory.
Hope that makes sense. I’m relatively new to utilising weak tables myself so more experienced users on that may have a better way of explaining it.
Edit: a few wording improvements and clarity. See replies for more info on how to make a table have weak keys, and for more info on Maid classes.