Images of the leak via LuaHeap before implementing a disconnection handler :
Player.CharacterAdded, Humanoid.Died, Humanoid.HealthChanged and so on do not disconnect upon their respective ancestors being destroyed/removed/respawned. When a player is removed, .CharacterAdded continues to take up memory (hours later), and the same goes for when a character respawns/dies. If a character respawns, Humanoid.Died is not called and left taking up memory, so :Once() is not relevant here. .HealthChanged stays alive even after Character destruction.
I had to implement individual connection disconnection handlers for each case in my game, this was an unexpected development hiccup as this is not the behaviour described on the documentation for Instance:Destroy().
This issue also occurs when running : task.spawn(function() Player.CharacterAdded:Connect … end) and likewise, it is important to note that :Start() is ran in a new thread as well (task.spawn(function() Module:Start() end) so this may be the cause.
Direct Link : [NEW] ⛽ fight at a gas station - Roblox
Expected behavior
I expect that connection such as .CharacterAdded, or Humanoid.Died or Humanoid.HealthChanged will be automatically disconnected upon destruction of the Player (player leaving) or Character objects respectively.
The fix :
Roblox documentation stating this behaviour is supposed to happen : Instance | Documentation - Roblox Creator Hub
If I did something wrong please correct me, but from my understanding I am not required to implement disconnection handlers for these events.