Sharksie
(Sharksie)
May 9, 2022, 6:36pm
#1
I should be allowed to lean on the luau garbage collector to trigger a cleanup function. This is useful with custom objects and other ephemeral data structures. I’d be significantly less prone to memory leaks if I could declare cleanup rules when I make the object rather than having to listen for some “no longer in use” trigger somewhere else in my codebase, then finding the object and cleaning it up.
9 Likes
This will almost certainly not happen.
Citing Sandboxing - Luau
Lua 5.1 exposes a __gc
metamethod for userdata, which can be used on proxies ( newproxy
) to hook into garbage collector. Later versions of Lua extend this mechanism to work on tables.
This mechanism is bad for performance, memory safety and isolation:
In Lua 5.1, __gc
support requires traversing userdata lists redundantly during garbage collection to filter out finalizable objects
In later versions of Lua, userdata that implement __gc
are split into separate lists; however, finalization prolongs the lifetime of the finalized objects which results in less prompt memory reclamation, and two-step destruction results in extra cache misses for userdata
__gc
runs during garbage collection in context of an arbitrary thread which makes the thread identity mechanism described above invalid
Objects can be removed from weak tables after being finalized, which means that accessing these objects can result in memory safety bugs, unless all exposed userdata methods guard against use-after-gc.
If __gc
method ever leaks to scripts, they can call it directly on an object and use any method exposed by that object after that. This means that __gc
and all other exposed methods must support memory safety when called on a destroyed object.
Because of these issues, Luau does not support __gc
. Instead it uses tag-based destructors that can perform additional memory cleanup during userdata destruction; crucially, these are only available to the host (so they can never be invoked manually), and they run right before freeing the userdata memory block which is both optimal for performance, and guaranteed to be memory safe.
For monitoring garbage collector behavior the recommendation is to use weak tables instead.
7 Likes