Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lua weak tables memory leak

I don't use often weak tables. However now I need to manage certain attributes for my objects which should be stored somewhere else. Thats when weak tables come in handy. My issue is, that they don't work es expected. I need weak keys, so that the entire key/value pair is removed, when the key is no longer referenced and I need strong values, since what is stored are tables with meta information which is only used inside that table, which also have a reference to the key, but somehow those pairs are never collected.

Code example:


local key = { }
local value = {
        ref = key,
        somevalue = "Still exists"
}

local tab = setmetatable({}, { __mode = "k" })

tab[key] = value

function printtab()
        for k, v in pairs(tab) do
                print(v.somevalue)
        end
end

printtab()

key = nil
value = nil

print("Delete values")
collectgarbage()

printtab()

Expected output:

Still exists
Delete values

Got:

Still exists
Delete values
Still exists

Why is the key/value pair not deleted? The only reference to value is effectivly a weak reference inside tab, and the reference inside value is not relevant, since the value itself is not used anywhere.

like image 434
Sewbacca Avatar asked Sep 10 '25 03:09

Sewbacca


1 Answers

Ephemeron tables are supported since Lua 5.2.
The Lua 5.2 manual says:

A table with weak keys and strong values is also called an ephemeron table. In an ephemeron table, a value is considered reachable only if its key is reachable. In particular, if the only reference to a key comes through its value, the pair is removed.

Lua 5.1 does not support ephemeron tables correctly.

like image 200
Egor Skriptunoff Avatar answered Sep 13 '25 09:09

Egor Skriptunoff