Garbage Collection, Memory Leaks, and Maid Class

So, I’m using maid to manage my connections, but I was wondering for things such as:

-- *Script inside of ServerScriptService*

game.Players.PlayerAdded:Connect(function()
--> Other connections in here, such as CharacterAdded, which are managed by Maid
end)

Would I have to handle the PlayerAdded connection with maid? Or, would it GC on its own?

Likewise, I have a LocalScript in StarterPlayerScripts:

Player.CharacterAppearanceLoaded:Connect(function()
--> Again, other connections in here, such as ChildAdded, which are managed by Maid
end)

Would the CharacterAppearanceLoaded connection have to be managed by maid, or would it GC when a player leaves?

I believe my game is suffering from a small memory leak, and I think the issue may be here.

EDIT:
I’ve attached a Maid handler to the PlayerAdded connection doing this:

maid:GiveTask(game.Players.PlayerAdded:Connect(function(player)
maid:GiveTask(player.AncestryChanged:Connect(function(child, parent)
		if not parent then
			maid:DoCleaning()
		end
	end))
end))

I’m pretty confident that this works, but am still curious about the LocalScript in StarterPlayerScripts.

2 Likes

You shouldn’t have to handle the player events with maid, roblox should automatically disconnect all events related to the player when they leave. For the PlayerAdded event, in what case would you want to disconnect it? I don’t see any reason to do so.

1 Like

Here’s some pseudo code, for reference:

Script in SSS:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Maid = require(ReplicatedStorage.Modules:WaitForChild("Maid"))
local maid = Maid.new()
maid:GiveTask(game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local maid = Maid.new()

		maid:GiveTask(player.Backpack.ChildAdded:Connect(function(tool)
			--> Stuff
		end))

		maid:GiveTask(character.AncestryChanged:Connect(function(child, parent)
			if not parent then
				maid:DoCleaning()
			end
		end))

	end)

	maid:GiveTask(player.AncestryChanged:Connect(function(child, parent)
		if not parent then
			maid:DoCleaning()
		end
	end))
end))

This script would run as long as the server is running, so I’d have to disconnect the PlayerAdded connection, I believe.

LocalScript in StarterPlayerScripts:

local Player = game.Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Maid = require(ReplicatedStorage.Modules:WaitForChild("Maid"))
local maid = Maid.new()

maid:GiveTask(Player.CharacterAppearanceLoaded:Connect(function()
	local Character = Player.Character or Player.CharacterAdded:Wait()

	maid:GiveTask(Player.Backpack.ChildAdded:Connect(function(child)
		--> Stuff
	end))

	-- Maid cleans up when the character is removed or respawns
	maid:GiveTask(Character.AncestryChanged:Connect(function(_, parent)
		if not parent then
			maid:DoCleaning()
		end
	end))
end))

This is where I’m stuck.
(Sorry if the code blocks are long)

1 Like

if you disconnect the PlayerAdded, nobody who joins will be able to play

1 Like

This script would run as long as the server is running, so I’d have to disconnect the PlayerAdded connection, I believe.

You still shouldn’t disconnect PlayerAdded event, that runs for every player that joins the game.

1 Like

I’ve tested it, and it works fine. I believe that it’s connecting to each player individually, so it doesn’t clear the connections for everyone.

If it works fine then you’re probably doing something else because disconnecting PlayerAdded will stop the script from detecting new players who join the game

2 Likes

Whoops nvm ur right… :man_facepalming:
So i wouldn’t have to worry about the script in sss leaking, because it should be running for the duration of the server life, right? (as long as i clean up the character connections)

Indeed. I believe you can also remove the maid handlers on the client side from the events related to the player (not the character), as they should be cleaned up when the player leaves.

Wouldn’t i have to manage the connections within the CharacterAppearanceLoaded connection? Such as ChildAdded? Here’s something I’m unclear about:

If there’s a connection (parent connection) within a connection (child connection); when the parent connection is disconnected, is the child connection disconnected by extension?

Wouldn’t i have to manage the connections within the CharacterAppearanceLoaded connection? Such as ChildAdded?

You could try that out for yourself, but i don’t think you do, as the player always exists, it’s your character that gets deleted / remade every time you respawn.

If there’s a connection (parent connection) within a connection (child connection); when the parent connection is disconnected, is the child connection disconnected by extension?

Afaik they aren’t.

1 Like

This might not actually be the case. Up until very recently when the player leaves Roblox sets its parent to nil instead of destroying it.

The source even mentions that if you have many connections to players that aren’t disconnected, it can create memory leaks for your game.

3 Likes

I was able to explain to @Polynovuh over Discord how to properly use maid class and explain how garbage collector works. And basically, you don’t need to disconnect most native events like PlayerAdded/Connected, unless they loop and need to be halted.

1 Like

Sorry; just for clarity, but i more than likely have to manage the connections in SSS, then?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.