Introduction
Hello, I am making this tutorial since I used to be bad at optimization (and probably still am) and I want to make sure everyone is informed. but there’s this one detrimental cause for memory leaks that will be definitely occur if you have a popular game and I wanna make sure no one has to deal with it.
You might think you know about it if you’re a experienced scripter, but I told this information to scripters who have been scripting for 10x longer than I have (I’ve only been scripting for under one year) and even they didn’t know about this.
So what is this huge memory leak?
Basically, whenever you fire the player removing/character removing event. You’d expect the instance to have already been destroyed right? WRONG.
The engine does not automatically destroy player/character objects even after their respective events have fired, this means that things such as attributes being saved to a player. Events being connected to the player/character will continue to use up memory.
Why is this so detrimental?
As more users join and leave the experience memory usage will continue to grow, to the point that you get a huge memory leak.
This memory leak will be on the server.
Server memory leaks are particularly nasty because servers can run up for days or even weeks! Making it a bad experience for everyone and feeling like it’s everywhere.
Atleast with client memory leaks it’s only for the specific client and no one else is affected, and ends once the client leaves the game.
Why are memory leaks bad?
Memory usage is the amount of RAM or swap that your experience uses. Even if an experience has low starting memory usage, memory leaks can cause that amount to increase over time.
On the server, excessive memory usage can cause crashes, which disconnect all players from the experience.
Excessive memory usage causes client crashes, too, but it also prevents users on lower-end devices from playing your experience in the first place. Reducing memory usage can greatly expand your addressable audience, especially on mobile.
How do I fix this?
Simply destroy the player/character object on their respective removing events once you’re done using them.
Sample code:
Players.PlayerAdded:Connect(function(player)
player.CharacterRemoving:Connect(function(character)
-- Pretend i'm doing other stuff before destroying it
task.defer(character.Destroy, character)
end)
end)
Players.PlayerRemoving:Connect(function(player)
-- Pretend i'm doing other stuff before destroying it
task.defer(player.Destroy, player)
end)
Thank you to the post that gave the idea of using task.defer instead of just destroying, And make sure to wrap in pcalls.
Also make sure to repeat this until it’s successful:
Players.PlayerAdded:Connect(function(player)
player.CharacterRemoving:Connect(function(character)
-- Pretend i'm doing other stuff before destroying it
repeat
local success = pcall(function()
task.defer(character.Destroy, player)
end)
task.wait()
until success
end)
end)
Players.PlayerRemoving:Connect(function(player)
-- Pretend i'm doing other stuff before destroying it
repeat
local success = pcall(function()
task.defer(player.Destroy, player)
end)
task.wait()
until success
end)