Lua弱引用及泄露检测

Lua中的弱引用,类似C#中的 WeakReference,可以判断对象是否存活,进而判断是否有泄露


Lua弱引用表

  • table 中的的key或者value如果不想引用住赋值进来的对象(其实就是table)的话,只需要一行代码 setmetatable(objTab, {__mode = "k"}); ,测试代码如下,

    local function TestWeakRef( )
        local objTab = {}
        setmetatable(objTab, {__mode = "k"}); -- 设置 objTab 中的 key 为弱引用
        local gTab = nil
    
        for i=1,5 do
            local tab1 = { key1 = "aaa"}
            objTab[tab1] = i
            -- gTab = tab1 -- 强引用
        end
    
        collectgarbage("collect") -- 强制垃圾回收
    
        for k,v in pairs(objTab) do
            print(k, v)
        end
    end
    • objTab 将print不出任何东西,是因为 objTab 中的 key或者value 被回收掉,为nil值,所以不会遍历出来。(如果想value也为弱引用的话这里改为 __mode = "kv"}

泄露检测的思路

  • 把实例化出来的对象丢到 弱引用表 中,一般都会有个最基础的类用于泄露检测或者对象池的操作,与 业务 和 功能 无关,

    -- 简易版对象
    local CObjBase = {}
    CObjBase.__index = CObjBase
    CObjBase.New = function(self)
        local t = {}
        self._alive = true
        self._stackInfo = debug.traceback("", 1) -- 可以加入一些堆栈信息,正式版需要去掉这些无用调试信息
        setmetatable(t, CObjBase)
        return t
    end
    CObjBase.Destroy = function(self)
        self._alive = false -- 主动销毁标记
    end
    
    local function TestWeakRef( )
        local objTab = {}
        setmetatable(objTab, {__mode = "k"}); -- 设置 objTab 中的 key 为弱引用
        local gTab = nil
    
        for i=1,5 do
            local tab1 = CObjBase:New() -- 模拟实例化一个对象
            setmetatable(tab1, CObjBase); 
            tab1:Destroy()
    
            objTab[tab1] = i
            gTab = tab1 -- 模拟某一地方强引用造成,泄露
        end
    
        collectgarbage("collect") -- 强制垃圾回收
    
        for k,v in pairs(objTab) do
            print(k._alive, k._stackInfo) -- 如果存在的对象的 _alive 标记为 false,这说明该该对象泄露了
        end
    end
    • 结果

      false
      stack traceback:
      F:\lua-5.3.0\aaa.lua:93: in method 'New'
      F:\lua-5.3.0\aaa.lua:104: in local 'TestWeakRef'
      F:\lua-5.3.0\aaa.lua:127: in main chunk
      [C]: in ?
      [Finished in 0.1s]

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蝶泳奈何桥.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值