Weak Tables and Garbage Collection
Prerequisites: Metatables and metamethods
Lua manages memory automatically with a garbage collector (GC): values that nothing refers to any more are freed.
local before = collectgarbage("count")
do
local big = {}
for i = 1, 100000 do big[i] = i end
end
local during = collectgarbage("count")
collectgarbage()
local after = collectgarbage("count")
print(during > before, after < during)
true true
collectgarbage("count") returns memory in use (in KB);
collectgarbage() runs a full collection. Lua 5.4 also offers a
generational mode (collectgarbage("generational")), often faster for
programs that create many short-lived objects.
Weak tables
A normal table keeps its keys and values alive. A weak table doesn't: if the only reference to an object is from a weak table, the GC can collect it.
local cache = setmetatable({}, {__mode = "k"}) -- weak keys
local obj1, obj2 = {}, {}
cache[obj1] = "data for obj1"
cache[obj2] = "data for obj2"
obj1 = nil
collectgarbage()
local count = 0
for _ in pairs(cache) do count = count + 1 end
print(count)
1
__mode = "k"— weak keys;"v"— weak values;"kv"— both.- Weak-keyed tables attach extra data to objects without keeping them alive — ideal for caches and per-object metadata.
Finalizers
local Resource = {}
Resource.__gc = function(r) print("releasing " .. r.name) end
do
local r = setmetatable({name = "texture"}, Resource)
end
collectgarbage()
print("after collect")
releasing texture
after collect
A __gc metamethod runs when the object is collected — but when that
happens isn't predictable. For files, sockets, and locks, release
resources explicitly or with a <close> variable (Lua 5.4), and treat
__gc as a safety net.