lua学习笔记之垃圾收集

1、弱表

弱表如何声明呢?通过元表字段__mode来声明,其值必须是字符串,"k"表示关键字是弱的,"v"表示值是弱的,"kv"表示键和值都是弱的。对象才可以收集,数字,布尔,字符串类型的不可以收集。

2、记忆化函数

通过表来记录计算结果,避免下次的重复计算。同时使用弱表来在没有引用时,通过垃圾收集自动处理

local results = {}
setmetatable(results, {__mode = "kv"})
function mem_loadstring(s)
    local res = results[s]
    if res == nil then
        res = assert(load(s))
        results[s] = res
    end
    return res
end

3、弱表实现默认值

local defaults = {}
setmetatable(defaults, {__mode = "k"})
local mt = {__index = function(t) return defaults[t]  end}

function setDefault(t, d)
    defaults[t] = d
    setmetatable(t, mt)
end

不同的默认值使用不同的元表,同时使用记忆化特性

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

function setDefault(t, d)
    local mt = metas[d]
    if mt == nil then
        mt = {__index = function() return d  end}
        metas[d] = mt
    end
    setmetatable(t, mt)
end

4、虚表

do
    local mem = {}
    setmetatable(mem, {__mode = "k"})
    function factory(o)
        local res = mem[o]
        if not res then
            res = (function() return o  end)
            mem[o] = res
        end
        return res
    end
end

因为mem表中的键值对应的是闭包,而闭包又引用键值,导致环。严格的解释器是不会收集key的。

lua中对于表的键值为弱的,而值不是弱的,视为虚表。

5、终结器

lua通过元方法__gc来实现终结器

o = {x = "hi"}
setmetatable(o, {__gc = function(o) print(o.x)  end})
o = nil
collectgarbage()
输出为:
hi

 如果在设置元表时,没有设置__gc,后面在通过__gc字段设置不起作用。

o = {x = "hi"}
mt = {}
setmetatable(o, mt)
mt.__gc = function(o) print(o.x)  end
o = nil
collectgarbage()

输出:
没有输出

 在上面情况时,可以先设置元表的标识为true,在设置元表后,再通过字段设置,也是可以的

o = {x = "hi"}
mt = {__gc = true}
setmetatable(o, mt)
mt.__gc = function(o) print(o.x)  end
o = nil
collectgarbage()
输出:
hi

在收集相关联对象时,关联关系不会影响收集顺序

 以单链表为例

mt = {__gc = function(o) print(o[1])  end}
list = nil
for i = 1, 3 do
    list = setmetatable({i, link = list}, mt)
end

list = nil
collectgarbage()

输出为:
3
2
1

当终结器执行时,会将终结的对象作为参数传递给它,此时对象为短暂复活,执行完后,作为永久复活

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kgduu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值