local t=setmetatable({},{__mode='k',})
game:GetService'Players'.PlayerAdded:Connect(function(plr)
local x={}
t[x]=true
plr.CharacterAdded:connect(function(char)
print(x)
end)
end)
while wait()do
local n=0
for k,v in next,t do n=n+1 end
print(n)
end
So if you run the above code in a server script in a one player local server, you can see that the even after the player leaves the game, the table is not garbage collected and thus the output remains ‘1’
BUT if you manually disconnect the CharacterAdded connection on PlayerRemoving, the output changes to ‘0’ after [a little time after] the player leaves the game:
local t=setmetatable({},{__mode='k',})
local cons={}
game:GetService'Players'.PlayerAdded:Connect(function(plr)
local x={}
t[x]=true
cons[plr]=plr.CharacterAdded:connect(function(char)
print(x)
end)
end)
game:GetService'Players'.PlayerRemoving:Connect(function(plr)
cons[plr]:Disconnect()
cons[plr]=nil
end)
while wait()do
local n=0
for k,v in next,t do n=n+1 end
print(n)
end
This doesn’t just happen for the CharacterAdded connection, it happens for ALL signals in the player object (well I only tested CharacterAdded, Chatted, and DescendantRemoving)
Is this one of the demons that have been making untracked memory climb stupidly high without going down? I never even knew this was a thing.
Might this not have to do with connections though? I thought that the Player instance is destroyed, thus disconnecting all connections and promptly having it garbage collected.
You have an upvalue reference to the Player instance. This isn’t a bug so much as an implementation detail, as this happens with all Instances (see this thread). What you might want is to request that Player Instances have their connections disconnected when they leave the game, since that’s the root cause here, but again, this isn’t a bug.
there is no upvalue to the player instance
locals are only designated as upvalues if they are used in a child function
the only upvalues in the first script are t and x
and yes, the bug is that ‘player connections are not disconnected on player leave’
the player object should be destroyed (it seems like the parent is locked to ‘null’), but the events are not disconnected
The player is being referenced indirectly by the CharacterAdded event. Since it’s still active, it’s preserving the Player instance. Even if it’s not an upvalue, this is still expected behavior for Instances and you would have to request it be changed for players specifically.
it really isnt being indirectly referenced
the table x and the function print(* that was another upvalue i missed) cannot be reached by the player object
expected behavior for instances is disconnectting connections on instance destroy see the devhub if you don’t believe me
As OP explains this isn’t expected behavior. One would expect the player is :Destroy()'d when they leave the game, killing all active connections. This does not seem to be the case.
What I’m saying is that I don’t think it’s defined that Players are actually destroyed when they leave.
I’m not disagreeing with that this is unexpected behavior, but if you go at this under the assumption that the Player Instance just quits existing rather than it being destroyed when the player’s removed, it makes perfect sense.
id like an engineer to say that this isnt a bug and provide a reason for it because I find this hard to believe
no in that case the connections should still be gced by the garbage collector because I am storing no strong references myself
something else is keeping these connections persistent
is it documented that it memory leaks intentionally?
are all bug reports feature requests under disguise because the wiki doesn’t rigorously and completely define the roblox engine? (which would be impossible anyways without the source code/ a complete description of the source code, white space etc)
so whats the point of bug reports then?
As I said, this is because you have an active connection to the Player instance, which count as a reference to the Instance. This is documented behavior and is an implementation detail.