Lua 5.4 Generational GC: Tuning Pause and Step Parameters
0 reputation · 03 May 2022, 07:06 UTC
0 reputation · 03 May 2022, 07:06 UTC
Lua 5.4 adds a generational mode that must be enabled with collectgarbage('generational'). The mode changes how the collector ages objects and can alter the impact of the traditional pause and step settings.
When the generational collector is active, the relationship between pause and step and the resulting pause latency is not well documented. Existing guidance treats these parameters as if the collector were incremental, but the generational algorithm may respond differently to the same values.
What are the recommended values for pause and step when using the generational mode? How does the generational algorithm modify the expected pause behavior compared to the standard incremental collector?
34775 reputation · 03 May 2022, 09:27 UTC
When the generational collector is enabled via collectgarbage('generational'), a good initial configuration is:
pause = 100 (percent of current memory before a GC cycle is triggered)step multiplier = 200 (work done per incremental step)These values are a baseline; adjust them based on measured pause latency or allocation rate.
Likely explanation (based on the generational design): The pause parameter primarily controls how often the young generation is collected. A lower pause causes more frequent minor collections, which are typically short, thus reducing the worst‑case pause latency but increasing overhead. The step multiplier influences the amount of work done in each incremental step of both minor and major collections; raising it shortens total GC time but can lengthen individual step pauses.
Confirmed facts from Lua 5.4 source: The generational mode splits objects into young and old generations. Minor collections scan only the young generation; major collections occur when the old generation grows enough to trigger a full cycle. The pause and step multiplier parameters are still interpreted as percentages and multipliers exactly as in the incremental collector, but their impact on pause latency is mediated through the frequency and cost of minor versus major cycles.
collectgarbage('generational')pause=100, step=200) via the C API or lua_gc.lua_gc(L, LUA_GCSTEP, 0) with timestamps.pause (e.g., to 50) to trigger more frequent, shorter minor collections.step multiplier (e.g., to 300) to do more work per step, but watch for longer step pauses.To refine the suggestion, we need to know the observed allocation rate (bytes per second) or the measured average minor‑GC pause latency for your application. If the allocation rate is very high, a lower pause may be necessary; if minor pauses are already negligible, you could raise pause to reduce overhead.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 03 May 2022, 12:10 UTC
In generational mode the pause percentage still gates when the collector starts a cycle, but the trigger is evaluated against the total memory of both generations; a minor collection can therefore start even if the young generation is small, as long as the combined usage exceeds the pause threshold. The step multiplier limits the amount of work performed per incremental step, and generational mode batches these steps inside each minor or major cycle, so increasing step reduces the number of pauses per cycle but can lengthen each pause when the old generation needs scanning.