Does adding constant data into a table without ever removing it cause memory leaks?

I’m a tad worried with my games door system, and the possibility of memory problems arising. When players join the game, they get given an exterior and interior plot. Both those plots have doors. I add those doors into a table, and that table is used to track so I know which door a player is closest to. However, when a player leaves, I don’t delete the door from the table, as I am unsure how to track what door actually needs to be deleted. Can see in code below I have a commented out the part that would ‘fire’ when a player leaves. However, as the player has left, it means their build is destroyed (removed) and thus I can’t track where in the table their door was.

for _, v in pairs(Exteriors:GetChildren()) do
    -- Plot already taken
    if v.Name ~= 'Empty' then
        local Build = v:FindFirstChild('Build')
        if Build then
            local Door = Build:FindFirstChild('Door')
            if Door then
                table.insert(AllDoors, Door.PrimaryPart)
                
                -- Get hinges
                local Hinge = Door.Door:FindFirstChild('Hinge')
                if Hinge then
                    DefaultHingePositions[Hinge] = Hinge.CFrame
                end
                
                Door.PrimaryPart.Touched:Connect(function(hit)
                    Teleport(hit, Door)
                end)
            end
        end
    end
    
    v:GetPropertyChangedSignal('Name'):Connect(function()
        if v.Name == 'Empty' then
            -- Need to find way of knowing who left, thus remove their door
        else
            local Build = v:FindFirstChild('Build')
            if Build then
                local Door = Build:FindFirstChild('Door')
                if Door then
                    table.insert(AllDoors, Door.PrimaryPart)
                    
                    -- Get hinges
                    local Hinge = Door.Door:FindFirstChild('Hinge')
                    if Hinge then
                        DefaultHingePositions[Hinge] = Hinge.CFrame
                    end
                    
                    Door.PrimaryPart.Touched:Connect(function(hit)
                        Teleport(hit, Door)
                    end)
                end
            end
        end
    end)
end

In short, would this be problematic? Or can I just keep adding items into the table forever, and not have any problems? I’m not sure if this is exactly what’s causing a memory leak, but it seemed to slowly build up over the course of 20-30 minutes as people joined and left the game.

From my understanding of how Roblox garbage collection works, is when the object is no longer referenced anywhere, it will clean up.

However, since this is a dictionary like so,

local reference = {
a = workspace.Object;
}
workspace.Object:Destroy()

a is actually still referencing Object, so it isn’t going to free up that allocation in memory until either reference becomes nil, or the reference to Object, a becomes nil.

Ideally, by removing resources in your arrays that you don’t need anymore would be great, that’s what I generally try to do depending on what I’m designing.

Anyone feel free to correct me if I’m wrong

I figured that might have been the case :confused: How can I remove the item from the table, or set it to nil or whatever, when the items been destroyed tho?

Forgive me as I sort of just skimmed over your code, but what if you whipped up a function that runs each time one of those parts is removed from the game using .ChildRemoved on the model, then you could run a recursive function that iterates over everything in your dictionary, searching for the part removed. If it finds the part in the dictionary, you can then set the key/index for that part to nil.

I hope that helps, can clarify a bit if necessary.

My friend suggested this edit

for _, v in pairs(Exteriors:GetChildren()) do
	local door;
	local hinge
	
	-- Plot already taken
	if v.Name ~= 'Empty' then
		local Build = v:FindFirstChild('Build')
		if Build then
			local Door = Build:FindFirstChild('Door')
			if Door then
				table.insert(AllDoors, Door.PrimaryPart)
				door = Door.PrimaryPart;
		
				-- Get hinges
				local Hinge = Door.Door:FindFirstChild('Hinge')
				if Hinge then
					table.insert(AllHinges, Hinge)
					--AllHinges[Hinge] = Hinge.CFrame
					hinge = Hinge
				end
		
				Door.PrimaryPart.Touched:Connect(function(hit)
					Teleport(hit, Door)
				end)
			end
		end
	end
	
	v:GetPropertyChangedSignal('Name'):Connect(function()
		if v.Name == 'Empty' then
-- REMOVE DOOR
			print(door)
			AllDoors[table.find(AllDoors, door)] = nil; 
			door = nil;
			
			AllHinges[table.find(AllHinges, hinge)] = nil;
			hinge = nil;
			print('Door removed', #AllDoors)
----------------------------
		else
			local Build = v:WaitForChild('Build', 5)
			local Door = Build:WaitForChild('Door', 5)
			
			if Build and Door then
				table.insert(AllDoors, Door.PrimaryPart)
				door = Door.PrimaryPart;
				
				-- Get hinges
				local Hinge = Door.Door:FindFirstChild('Hinge')
				if Hinge then
					table.insert(AllHinges, Hinge)
					hinge = Hinge
				end
				
				Door.PrimaryPart.Touched:Connect(function(hit)
					Teleport(hit, Door)
				end)
				
				print('Onstart',#AllDoors)
			end
		end
	end)
end

Of having a local variable for every exterior, and the setting it to the door, that way when the player leaves, I can remove the door from the table. Is this efficient? Look for the – REMOVE DOOR line