luagarbage-collectionffiluajit

Lua why does the __gc metamethod is never ran here?


I'm struggling to understand why is the __gc metamethod is not being called here. I immediately removed the reference to x and triggered a GC, so why?

local obj = {}
obj.__index = obj

function obj:__gc()
  print("gc")
end

function new()
  return setmetatable({}, obj)
end

local x = new()
x = nil
collectgarbage()

I expect that the GC would collect that x and so it would trigger the __gc metamethod associated with it.

This is just a minimal reproducible example but to make my goals clear I want to wrap a C data in LuaJIT's ffi to deallocate its memory upon garbage collection.


Solution

  • I just found about ffi.metatype which allows me to attach a metatable with __gc e.g:

    local ffi = require("ffi")
    local mt = {}
    local obj = ffi.metatype("struct { int x; }", mt)
    
    function mt:__gc()
      print("gc")
    end
    
    function new()
      return obj(5)
    end
    
    local x = new()
    x = nil
    collectgarbage()
    

    Since I need to wrap a C pointer, this is just right for me.