lua GC垃圾收集 内存优化


lua垃圾收集函数:

 

  collectgarbage("collect"): 做一次完整的垃圾收集循环。通过参数 opt 它提供了一组不同的功能:

 

 

  collectgarbage("count"): 以 K 字节数为单位返回 Lua 使用的总内存数。 这个值有小数部分,所以只需要乘上 1024 就能得到 Lua 使用的准确字节数(除非溢出)。

 

 

  collectgarbage("restart"): 重启垃圾收集器的自动运行。

 

 

  collectgarbage("setpause"): 将 arg 设为收集器的 间歇率 (参见 §2.5)。 返回 间歇率 的前一个值。

 

 

  collectgarbage("setstepmul"): 返回 步进倍率 的前一个值。

 

 

  collectgarbage("step"): 单步运行垃圾收集器。 步长"大小"由 arg 控制。 传入 0 时,收集器步进(不可分割的)一步。 传入非 0 值, 收集器收集相当于 Lua 分配这些多(K 字节)内存的工作。 如果收集器结束一个循环将返回 true 。

 

  collectgarbage("stop"): 停止垃圾收集器的运行。 在调用重启前,收集器只会因显式的调用运行。

如下工具可以统计lua中的某个文件中某一行带来的内存分配和消耗:

  

local memory_state = {} -- 储存所有的内存调用
local current_memory = 0 -- 储存总内存状态

local function recordAlloc(event, line_no)
    local memory_increased = collectgarbage("count") - current_memory
    if (memory_increased < 1e-6) then return end

    local info = debug.getinfo(2, "S").source
    info = string.format("%s@%s", info, line_no - 1)

    local item = memory_state[info]
    if not item then
        memory_state[info] = {info, 1, memory_increased}
    else
        item[2] = item[2] + 1
        item[3] = item[3] + memory_increased
    end
    current_memory = collectgarbage("count")
end

utilsMemoryLeakDetector = {}

function utilsMemoryLeakDetector:StartRecord()
    if debug.gethook() then
        self:StopRecord()
        return
    end

    memory_state = {}
    current_memory = collectgarbage("count")
    debug.sethook(recordAlloc, "l")
end

function utilsMemoryLeakDetector:ShowRecord(count)
    if not memory_state then return end
    local sorted = {}

    for k, v in pairs(memory_state) do
        table.insert(sorted, v)
    end

    table.sort(sorted, function(a, b) return a[3] > b[3] end)

    for i = 1, count do
        local v = sorted[i]
        print(string.format("MemoryDump [MEM: %sK] [COUNT: %s ] [AVG: %s k] %s:", v[3], v[2], v[3] / v[2], v[1]))
    end
end

function utilsMemoryLeakDetector:EndRecord()
    debug.sethook()
end

utilsMemoryLeakDetector:StartRecord()

if IsInToolsMode() then
    Convars:RegisterCommand("debug_dump_lua_memory_detail",function(_, top_count)
        count = tonumber(top_count) or 30
        utilsMemoryLeakDetector:ShowRecord(count)
    end,"Dump lua usage",FCVAR_CHEAT)
end

 

posted on 2020-03-31 16:00  123_123  阅读(677)  评论(0编辑  收藏  举报