Tracking memory leaks

My game has 400+ MB of Untracked Memory. The game is quite large and there are numerous scripts in the game. How can I figure out which scripts are the cause of the memory leaks so I can fix them?

4 Likes

A common cause of memory leaks are undisconnected connections. You could try this:

  • Hold Ctrl+shift+f
  • Search “:Connect” and “:ConnectParallel”
  • Open the scripts that have this
  • Check the connections and disconnect any you don’t need
4 Likes

How do I know if I need/don’t need the connections?

3 Likes

Just simply by logic. For example, if you have a part that needs a .Touched connection temporarily (e.g. for a race system), you would create it:

local connection = part.Touched:Connect(someRandomFunctionHere)

Then, when that race ended, you don’t need that connection anymore, but it’s still there. So, you get rid of it.

connection:Disconnect()

If you need a connection to only happen once, you can use :Once instead of :Connect.

4 Likes

What if the race game is round based? Then after the race ends an intermission starts. After the intermission, another race begins. You wouldn’t disconnect it because it is needed again, right?

2 Likes

Yeah, if it’s the same part, you would keep it connected. That was simply an example. Another example could be connections related to the player on the server, you would need to disconnect those when the player leaves.

3 Likes

TL;DR: When connections are not disconnected, they persist in memory even if the objects they are connected to are no longer needed or have been destroyed. This can lead to increased memory usage and eventually cause performance issues.

Imagine you have a part that players can touch to receive a reward. You create a connection to the Touched event but forget to disconnect it when it’s no longer needed. Here’s how this can cause a memory leak:

local function giveReward(player)
    -- Code to give the player a reward
    print(player.Name .. " received a reward!")
end

local function setupRewardPart(part)
    part.Touched:Connect(function(hit)
        local character = hit.Parent
        local player = game.Players:GetPlayerFromCharacter(character)
        if player then
            giveReward(player)
        end
    end)
end

-- Example of creating multiple reward parts over time
for i = 1, 10 do
    local part = Instance.new("Part")
    part.Parent = workspace
    setupRewardPart(part)
end

In the code above, each time setupRewardPart is called, a new connection to the Touched event is created. If these parts are later destroyed or are no longer needed, the connections remain in memory because they were never disconnected. This leads to a memory leak.

To prevent this, you need to ensure that you disconnect the event connections when they are no longer needed. This is usually done when the part is destroyed or some sort of clean-up function is called.

Something like:

part.AncestryChanged:Connect(function(child, parent)
        if not parent then
            connection:Disconnect()
            print("Disconnected touch event for part")
        end
    end)
3 Likes

So this script (prevents players from colliding with each other) would need to have the connection disconnected when the player leaves?

local Players = game:GetService("Players")
local PhysicsService = game:GetService("PhysicsService")
local GroupName = "Players"

PhysicsService:CreateCollisionGroup(GroupName)
PhysicsService:CollisionGroupSetCollidable(GroupName, GroupName, false)

Players.PlayerAdded:connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)

		local function ChangeGroup(Part)
			if Part:IsA("BasePart") then
				PhysicsService:SetPartCollisionGroup(Part, "Players")
			end
		end

		Character.ChildAdded:Connect(ChangeGroup)
		for _, Object in pairs(Character:GetChildren()) do
			ChangeGroup(Object)
		end
	end)                                                
end)
2 Likes

Ideally you would want to disconnect from the CharacterAdded event when the player leaves the game. Not disconnecting isn’t a huge problem if your game is smaller, but memory leaks add up.

3 Likes

@JamesBlossoms

Thanks for clearing that up, I think I understand now

3 Likes