Memory leak due to Instances in Players not removing when they leave?

I’m having an issue with my game that’s getting memory leaks, which is really concerning (All related help-posts have been read previously). After hours of monitoring I figured that untracked memory spikes only when players leave/join and in an counter-intuitive manner, where if the player joins the game the Untracked memory spikes down & vice versa if the player leaves? This narrows down the search to Player handlers and as a way to further narrow the search for leaks I decided to run a while true do loop to see if the instances created in the player folders are actually removed after the players disconnect:

game.Players.PlayerAdded:Connect(function(Player)
 while wait(180) do --//Prints "Money" even if the player is removed from the players list and all of the instances are destroyed?
      print(Player.PlayerFolder.Money)
 end
end)

And it seems that the instances are not actually removed? So my question is, am I doing this correctly or am I forgetting something & could the memory leaks be caused by this?

To keep everything together, I’ve also found a good use of DataStore2 module by @Kampfkarren. However, it feels as though I’m using it incorrectly and starting to suspect that my code is contributing to more memory leaks? Currently, I cache the data whenever a value in the players’ folder is changed and save them after a certain amount of time, or after the player has bought a dev. product. Could this, combined with 5 more values changing every once in a while & 30+ players in the server be also causing leaks?

You’ve tried using RunService? I had a problem like yours and i fixed it changing the loops with RunService.Heartbeat, Hope this works.

I wish the issue was as simple as that. Unfortunately, that’s not what I’m looking for. This is surrounded with the fact that I’m having memory leaks, not loops, which I suspect to be caused by either instances not removing when the player leaves or my inappropriate usage of DS2.

local canBreak = false
while wait(180) do
game.Players.PlayerRemoving:Connect(function(player)
       for i,v in pairs(player:GetChidren()) do
       v:Destroy()
       end
       canBreak = true
end)
if canBreak then break end

(Just noticed this will only work if this canBreak is made in client.)

Yeah, this isn’t how lua’s garbage collector works.
When calling :Destroy(), you’re removing the instance and it’s children from the game (not memory). This disconnects any relevant connections with the instance (RBXScriptSignals), parents the instance to nil and locks the parent. But the instance will exist as long as it has references to it.

Lua’s garbage collector automatically handles memory, removing tables and userdata which nothing references. However, if a reference to a lua object still exists, then the garbage collector isn’t completely sure that the object is garbage unless user-defined.

So instances parented under removed players should not be posing a memory leak problem.
If you want to truly see if an instance has been removed from the game, try accessing/changing its parent.

1 Like

Hello. I am experiencing the same problem. Where you ever able to resolve it? If so, what was the problem?

I’ve been able to “hack” my way around it by lowering the player count. It seemed like the spikes started appearing after a certain threshold of players joined (somewhere over 40 plrs). Do note that this is a dirty workaround and not an actual solution, therefore it’s highly unadvised you go with this.

2 Likes