Search code examples
lua

Are finalizers called in the reverse order of making?


Consider the following code:

function fun()
   local o1 = foo:new() -- object with __gc metamethod
   local o2 = bar:new() -- object with __gc metamethod
end

Will Lua call the o2 finalizer before o1's because o2 was created later than o1 or is the order finalizers are called undefined?


Solution

  • It is guaranteed that o2 will be finalized before o1

    Objects will be finalized in the reverse order that they were "marked". An object is "marked" for finalization when the metatable is set with a __gc metamethod.

    Reference: https://www.lua.org/manual/5.4/manual.html#2.5.3

    At the end of each garbage-collection cycle, the finalizers are called in the reverse order that the objects were marked for finalization, among those collected in that cycle; that is, the first finalizer to be called is the one associated with the object marked last in the program. The execution of each finalizer may occur at any point during the execution of the regular code.

    For an object (table or userdata) to be finalized when collected, you must mark it for finalization. You mark an object for finalization when you set its metatable and the metatable has a __gc metamethod. Note that if you set a metatable without a __gc field and later create that field in the metatable, the object will not be marked for finalization.


    In this example o1 will be finalized before o2:

    function fun()
       local o1 = foo:new() -- object without __gc metamethod
       local o2 = bar:new() -- object without __gc metamethod
    
       setmetatable(o2, metaWithGC)
       setmetatable(o1, metaWithGC)
    
    end