lua内存泄漏问题解决

内存泄漏解决方案

snapshot是Lujit自带的库, 可以对所有lua对象做一次快照, 两次快照对比一下, 就知道第二次快照多了哪些对象, 在程序运行之初对所有引用的对象进行一次快照,程序结束之后再对所有引用的对象进行一次快照,然后对比两个快照便可以知道有没有内存泄漏:
以下是云风大大的测试用例:
    local snapshot = require('snapshot');
    -- 第一次快照
    local S1 = snapshot();
    local t = {};
    -- 第二次快照
    local S2 = snapshot();
    for k,v in pairs(S2) do
        if S1[k] == nil then
            -- 打印多出来的对象
            print(tostring(k), tostring(v));
        end
    end

但是有些情况下, 仍然不能解决问题, 例如当程序一直在运行, 并且是非线性的运行, 该如何检测内存泄漏呢?
有个办法是进行多次快照, 如果有些对象引用在多次快照中都存在, 则泄漏的可能性非常大。此时数据量也比较少, 容易看出问题来。
以下是代码提供:

local snapshot = require('snapshot');
local rr,ee = pcall(function()
    -- 让内存释放一会, 以20秒以后的快照为基准快照
    timer.setTimeout(20000, function()
        -- 获取第一张快照, 这张快照里面的对象引用都是不计入计算的
        local base = snapshot();

        local count = {};
        local S1 = nil;

        local diff = {};
        -- 弱引用, 弱引用表指向数据, 不影响数据的释放(数据被指向则不会释放)
        setmetatable(diff, {__mode = 'k'});
        setmetatable(count, {__mode = 'k'});
    -- 每隔十秒进行一次快照
        timer.setInterval(10000, function()
            writeLog(-1,{'******************************快照开始, 并对比*****************************'})
            -- 第二张快照
            local S1 = snapshot();

            for k,v in pairs(S1) do
                -- 如果第一张快照中不存在该数据的引用, 历次快照的区别中也不存在这个数据的引用,则该数据是本次快照和上次快照之间生成的数据, 保存起来, 加入到历次快照的区别中, 并记重复次数为1
                if diff[k] == nil and base[k] == nil then
                    writeLog(-1, {"出现次数:1", "key:"..tostring(k), "value:"..tostring(v)});
                    diff[k] = v;

                -- 如果历次快照的差别中有该数据的引用, 则说明该数据的引用已经重复出现,打印出来
                elseif diff[k] then
                    count[tostring(k)] = 1 + (count[tostring(k)] or 1)
                    writeLog(-1, {"出现次数:"..tostring(count[tostring(k)]), "key:"..tostring(k), "value:"..tostring(v)});
                end
            end
            writeLog(-1,{'********************************快照对比结束*******************************'})
        end)
    end)
end)

查看内存泄漏的对象:(出现次数自己定, 重复次数越高, 内存泄漏的可能性越大, 可以直接定100次, 然后查找重复一百次以上的对象, 其中程序初始化时的对象引用已经基本排除了, 所以内存泄漏不严重的情况, 数据量应该是不多的)

    grep -rn '出现次数:20' > 1
    vim 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值