🎓 A1Learner
🔍
0 of 52 lessons completed

Lua Garbage Collection

Garbage collection is Lua automatically reclaiming memory from values no part of the program can reach any more. It frees unreachable tables and other objects so a long program does not keep growing forever.

A full cycle runs on demand

Call collectgarbage("collect") to run a full cycle right away. The program below keeps working after the call.

local data = {10, 20, 30}
collectgarbage("collect")
print(data[1] + data[2] + data[3])

Dropping the last reference frees an object

The object below lives only in a weak slot after its variable is set to nil. A full cycle then empties that slot.

local cache = {}
setmetatable(cache, {__mode = "v"})
local obj = {name = "sword"}
cache[1] = obj
obj = nil
print(cache[1] ~= nil)
collectgarbage("collect")
print(cache[1] == nil)

A kept reference survives collection

A strong variable still pointing at an object protects it. The same cycle that emptied the last snippet leaves this object in place.

local kept = {name = "shield"}
local cache = {}
setmetatable(cache, {__mode = "v"})
cache[1] = kept
collectgarbage("collect")
print(cache[1] ~= nil)
print(cache[1].name)

Example

local function makeCache()
  local cache = {}
  setmetatable(cache, {__mode = "v"})
  local lost = {name = "potion"}
  cache[1] = lost
  return cache
end
local cache = makeCache()
local kept = {name = "map"}
cache[2] = kept
print(cache[1] ~= nil)
print(cache[2] ~= nil)
collectgarbage("collect")
print(cache[1] == nil)
print(cache[2] ~= nil)
print(cache[2].name)

Key points

  • Collector: the collector is the part of Lua that finds and frees unreachable values.
  • Unreachable: a value is unreachable when no variable, table slot, or other live value refers to it.
  • Full cycle: collectgarbage("collect") runs a full collection cycle at once.
  • Reachability: a value with even one strong reference stays alive through a collection cycle.
  • Weak reference: a weak table slot does not keep its value alive, so collection can empty it.

In this example, makeCache builds a weak-valued cache and returns only the cache, so the potion object has no strong reference once the function returns. The kept map object is stored in the cache and also in a strong variable. Before collection both slots hold an object. After a full cycle the potion slot is nil while the map slot still holds its object, and its name prints.

Note

Lua never promises exactly when automatic collection happens, so call collectgarbage("collect") when a demo must force a cycle.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

A weak-valued slot holds an object, its last strong variable is set to nil, and collectgarbage("collect") runs. What does the slot hold now?