Weak Tables, Finalizers and Garbage Collection
20.1 Garbage Collection
Lua uses automatic memory management with an incremental mark-and-sweep collector. 5.4 adds a generational mode.
print(collectgarbage("count")) -- memory in use (KB)
collectgarbage() -- full collection ("collect")
collectgarbage("step", 0) -- perform an incremental step
collectgarbage("incremental", 200, 100) -- 5.4: set pause and step multiplier
collectgarbage("generational") -- 5.4: switch to generational mode
collectgarbage("stop"); collectgarbage("restart")
print(collectgarbage("isrunning"))20.2 Weak Tables
Strings and numbers are values, not collectable objects for weak-table purposes: they're never removed from weak tables.
-- Weak keys: entries disappear when the key is no longer referenced elsewhere
local cache = setmetatable({}, {__mode = "k"})
local obj = {}
cache[obj] = "metadata"
obj = nil
collectgarbage()
for k, v in pairs(cache) do print(k, v) end --> (empty)
-- Weak values: memoization caches that don't prevent collection
local memo = setmetatable({}, {__mode = "v"})
-- Ephemeron tables (weak keys, strong values) avoid key-value cycles keeping keys alive (5.2+)
local properties = setmetatable({}, {__mode = "k"})
local function set_prop(o, name, value) properties[o] = properties[o] or {}; properties[o][name] = value end20.3 Finalizers (__gc)
Finalizers run at an unspecified time. Prefer explicit cleanup (or <close> variables in 5.4) for deterministic resource release.
Objects can be "resurrected" by their finalizer. Finalizers run in reverse order of marking. Errors in finalizers generate warnings (5.4).
local Resource = {}
Resource.__index = Resource
Resource.__gc = function(self) print("finalizing " .. self.name) end
function Resource.new(name) return setmetatable({name = name}, Resource) end -- __gc must be in the metatable when setmetatable is called
local r = Resource.new("temp")
r = nil
collectgarbage() --> finalizing temp