Metatable Behavior

Consider the code below:

local Main = {}
local Test = {}
setmetatable(Test, Main )
Main = nil
print(getmetatable(Test)) --> some table id

I was wondering how come this is still printing Test’s metatable’s (which is “Main”) id when I setted it to nil in the line prior?

UPDATE: I totally overthought the question, but if you want some neat information about Lua internals, it’s below I suppose.

When you write Main = nil, you’re not clearing the table from memory, you’re just clearing the reference. If there’s no references left, the table will be deleted from memory. setmetatable counts as a reference.

I’d love for someone who knows more about the internals of Lua to correct me on what I misinterpret/get wrong, but here’s my understanding.

In lua_setmetatable (the C function responsible for setting the metatable), this line tells Lua to cross an object over the Lua/C barrier.

https://github.com/rangercyh/lua5.1/blob/master/lapi.c#L727

luaC_objbarriert is a macro that’ll copy the table and mark the table as gray in garbage collection.

4 Likes

So even when it’s nil it’s still sitting there taking up data?

If this is true, I assume if there isn’t anything else referencing to, it it would get GC’d?

1 Like

Dang, you just answered my question right before I posted. Awesome. :slight_smile:

3 Likes

does it get GC when you do

setmetatable(Test,nil)

Since there is not reference left?

Yes (tested in Lua 5.1.4 with collectgarbage enabled):

local references = setmetatable({}, { __mode = "v" })

local mt = {}
references[#references + 1] = mt

local _table = setmetatable({}, mt)
mt = nil
collectgarbage()
print(#references) -- 1

setmetatable(_table, nil)
collectgarbage()
print(#references) -- 0

Does that work for RBLX Lua?

Can I do

local references = setmetatable({}, { __mode = "v" })

or it’s just for Lua

I do know that you can’t do

collectgarbage()

but you can check the Value

print(collectgarbage('Count'))

I think

The only reason I tested in standard Lua is because Roblox Lua does not allow the use of collectgarbage(). Yes, weak tables work just fine in Roblox Lua.

collectgarbage("count") will only show you how much memory is being taken. collectgarbage() actually forces a garbage collection cycle.

1 Like