Would this metatable module leak memory?

Ive made a module recently that is required by all clients at the same time locally. It uses metatables for showing local character visuals on all characters.
Here is a version with just the important parts:

local dynamicJoints = {}

dynamicJoints.__index = dynamicJoints


function dynamicJoints.start(player)
    print("started for player "..player.Name)
    
    local connectionTable = {}

    local function update(dt)
        print("hello")
        -- do stuff here
    end


    connectionTable.reset = game.ReplicatedStorage.Events.ResetDynamic.OnClientEvent:Connect(function(otherPlayer)
        -- reset stuff here
    end)
    
    connectionTable.update = game["Run Service"].RenderStepped:Connect(update)
    
    return setmetatable({
        connections = connectionTable
    }, dynamicJoints)
end

function dynamicJoints:stop()
    print("stopped")
    
    for _, connection in pairs(self.connections) do
        if connection and connection.Connected then
            connection:Disconnect()
        end
    end
    
    setmetatable(dynamicJoints, nil)
end

return dynamicJoints

If I called :stop() on this module and removed all variables referencing the metatable, would all the memory from the .start() function get removed? Or will there be some memory left over? Ive redone my code multiple times and I dont want to do it again, which is why Im asking here

Is there actually any way to test this? From what I know you cant see modules in the script performance window, so I cant check myself

1 Like

Assuming that by metatable you mean the dynamicJoints table that your module returns when requested, and if you remove all references to that table, then yes. All the memory occupied by the dynamicJoints table will eventually be recycled and there will be no memory leaks.

I noticed that dynamicJoints follows the pattern of a lua class and the :start() function is the constructor (and therefore :stop() the destructor). So when you create an object with :start() it occupies a place in memory (different from dynamicJoints) and keeps the reference to two connections. So that there are no memory leaks (with respect to this object), you must disconnect the connections (which is done in :stop()) and remove any reference to the object.

Recycling is done transparently, so it is not possible to know if something has been recycled or not.

2 Likes