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?
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
How do I know if I need/don’t need the connections?
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
.
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?
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.
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)
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)
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.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.