Skip to content

Lua Garbage Collection Guide — GC Tuning and Memory Management

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about Lua Garbage Collection Guide. We cover key concepts, practical examples, and best practices to help you master this topic.

Lua garbage collection runs incrementally to avoid long pauses, controlled by collectgarbage options for pausing (setpause), step multiplier (setstepmul), and step size (setstepsize) -- with generational mode in Lua 5.4+ for low-latency applications.

GC Control Functions

-- Force full GC cycle
collectgarbage("collect")

-- Count memory usage (in KB)
print(collectgarbage("count") .. " KB")

-- Stop GC
collectgarbage("stop")

-- Restart GC
collectgarbage("restart")

GC Parameters

-- Set pause (default 200)
-- Higher = longer pause between cycles
collectgarbage("setpause", 200)

-- Set step multiplier (default 200)
-- Higher = faster collection, more CPU
collectgarbage("setstepmul", 200)

-- Set step size (default varies)
collectgarbage("setstepsize", 100)

Generational Mode (Lua 5.4+)

-- Switch to generational mode
collectgarbage("generational", 0, 0)

-- In generational mode, GC focuses on
-- recently created objects (minor collections)
-- with occasional full sweeps (major collections)

-- Switch back to incremental
collectgarbage("incremental", 200, 200)

Memory Profiling

local function memoryUsage()
    local before = collectgarbage("count")
    
    -- Create some objects
    local t = {}
    for i = 1, 10000 do
        t[i] = {data = "x" .. i}
    end
    
    local after = collectgarbage("count")
    print("Memory used:", after - before, "KB")
    
    -- Clean up
    t = nil
    collectgarbage("collect")
end

memoryUsage()

Common Mistakes

1. Calling collectgarbage("collect") too often

Frequent full GC cycles hurt performance. Let the incremental GC work naturally.

2. Ignoring GC pauses for real-time applications

Incremental GC reduces but doesn't eliminate pauses. Use generational mode for games or interactive apps.

3. Memory leaks through closures

Closures capture their upvalues. A closure reference prevents all captured variables from being collected.

Practice Questions

1. How do you force garbage collection? collectgarbage("collect") performs a full GC cycle immediately.

2. What is the difference between incremental and generational GC? Incremental spreads collection over time. Generational (Lua 5.4+) does quick minor collections on new objects and rare full sweeps.

3. How do you measure Lua memory usage? collectgarbage("count") returns memory in kilobytes used by Lua.

FAQ

{{< faq question="Does Lua have a memory leak problem?" >}} Lua itself doesn't leak, but user code can via unintended references (closures, circular references with __mode not set, global variables). {{< /faq >}}

{{< faq question="What is the default GC mode?" >}} Incremental mode, which balances collection overhead and pause times. Generational mode is opt-in. {{< /faq >}}

{{< faq question="Can I disable GC entirely?" >}} Yes, with collectgarbage("stop"). Only do this if you manually manage memory or have a phase with no allocations. {{< /faq >}}

What's Next

Now learn about bit operations.

Topic Description Link
Bit Operations Bit manipulation in Lua {{< ref "27-bit-operations" >}}
Persistence Serialization and data storage {{< ref "28-persistence" >}}

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro