What is Garbage Collection and a Maid class?

I’ve had this question for a while, I see people talking about how useful they are and I feel like a lot of the posts talking about this don’t clarify exactly a lot of these things.

What I don’t understand

  1. Garbage Collection
    • What is it?
    • Why should I use it?
    • How do I implement it?
  2. Maid Classes
    • What is it?
    • Why should I use it?
    • How do I implement it?
  3. Memory Leaks
    • What are they?
    • Why do people avoid them?
    • What happens when a memory leak occurs?

Please explain much more simply than most of these posts, I have an idea of what weaktables (I think it’s when you can use objects as keys?) and I know very well what metatables are. Anyway, I hope to have a better idea of what Garbage Collection is soon!

6 Likes

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.

22 Likes

How does one actually make a weak table?

1 Like
local weak = setmetatable({}, {__mode = 'k'})
7 Likes

So this’d just be automatic? This is quite confusing.
cc @BanTech

Here’s an article on Maid Classes by Quenty. How to use a Maid class on Roblox to manage state | by James Onnen (Quenty) | Roblox Development | Medium

1 Like

Its when the NPC is removed from memory, not when destroyed.
The NPC can still exist in memory for some time after its destroyed even if it has no strong references.
(The Garbage Collector only runs every so often)

More info on the weird behavior of instances and weak tables
Just make sure the NPC model has a strong reference for the time it needs to be in the weak table.

Just going to put it out there that I asked a question on the Maid pattern some time ago, which you could’ve found by searching. That’d reduce your inquiry load by a bit down to garbage collection and how the Maid class plays a part in that.

1 Like