本文链接:https://www.cnblogs.com/dearplain/p/14771011.html
先记住一段话:lua weak table,可以设置table的key或者value变成弱引用,所谓弱引用就是说,如果这个key或者value在table外部没有引用,那么这个key或者value,就可以被gc回收。
举个例子:
local a = {} local b = {} setmetatable(a, b) b.__mode = "k" -- 表a的key是weak的 local key = {} a[key] = 1 key = nil -- 外部不再引用 collectgarbage() -- forces a garbage collection cycle for k, v in pairs(a) do print(v) end -- 发现什么都没打印
把value变成弱引用,那么效果也一样:
local a = {} local b = {} setmetatable(a, b) b.__mode = "v" -- 表a的value是weak的 local value = {} a[1] = value value = nil -- 外部不再引用 collectgarbage() -- forces a garbage collection cycle for k, v in pairs(a) do print(v) end -- 发现什么都没打印
所以那么这个key或者value,必须是对象,才能使用弱引用。
一个应用,一个临时对象的池:
local res = {} setmetatable(res,{__mode = "v"}) function createRGB(r, g, b) local key = r .. "-" .. g .. "-" .. b if res[key] then return res[key] else local newcolor = {red = r,green = g,blue = b} res[key] = newcolor return newcolor end end
观察上面的代码,如果我们去掉了
setmetatable(res,{__mode = "v"})
会发生什么问题?
由于createRGB会不断创建不同r g b的key value,这个数量很庞大,如果不再引用某个value,那么这个key又没有删除,那么内存会占用越来越大。
不过你会说,这个例子有点傻,为啥不直接写
{red = r,green = g,blue = b}
就好了,系统gc会自动回收。但是当创建某个对象是非常消耗时间或者资源的时候,这个例子就有了一定的意义。比如某些资源池、内存池。
参考:
https://www.cnblogs.com/hiker-online/p/13587037.html
https://www.cnblogs.com/kane0526/p/7458407.html