Re: upvalue memory leak.

  • From: "Robert G. Jakabosky" <bobby@xxxxxxxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Thu, 16 Aug 2012 18:06:56 -0700

On Thursday 16, Mike Pall wrote:
> 
> There's no easy way to avoid that. But I don't think this issue
> matters much for non-synthetic code, though.

Attached is a more valid use-case.  A closure is used to easily wrap a block 
of code with pcall() to catch any errors from the block, which is what I had 
done the first time I ran into this issue with the frag_tables.lua test-case.

In the attached case LuaJIT will only leak two tables created during the first 
two runs of the code, before it compiles a new trace and allows the upvalue to 
be collected from runs after the first two.  The tables from the first two 
runs are still not collectable.

This can be an issue if that block of code is part of a module and the 
prototype doesn't get collected.

-- 
Robert G. Jakabosky
local lim = tonumber(arg[1]) or 1000

local function mem()
        return math.floor(collectgarbage"count")
end

local function run_test()
        local upval = {}
        local stat, err = pcall(function()
                -- fill table at upvalue 'a' with lots of memory
                for i = 1, lim do
                        local t = {}
                        for x = 1, lim do
                                t[x] = x
                        end
                upval[i] = t
                end
        end)
end

for i=1,10 do
        run_test()

        collectgarbage"collect"
        print('Lua mem Kb=', mem())
end
collectgarbage"collect"
collectgarbage"collect"
collectgarbage"collect"
print('Lua mem Kb=', mem())

Other related posts: