Lua弱表Weak table

定义:弱表的使用就是使用弱引用,很多程度上是对内存的控制。

1、weak表示一个表,它拥有metatable,并且metatable定义了__mode字段。

2、弱引用不会导致对象的引用计数变化。换言之,一个对象只有弱引用指向它,那么gc会自动回收该对象的内存。

3、__mode字段可以取以下三个值:k、v、kv。任何情况下,只要key和value中一个被gc,那么key-value pair都被从表中移除了。

weak table 简单应用eg1:

a = {}
b = {}
setmetatable(a,b)
b.__mode = "k"  --now 'a' has weak keys

key = {}   --create first key
a[key] = 1

key = {}   --create second key 
a[key] = 2

for k,v in pairs(a) do
    print(v) --1   2
end
collectgarbage()  --forces a garbage collection cycle
for k,v in pairs(a) do
    print(v) --2  
    --[[第二个赋值语句key={}覆盖了第一个key的值。当垃圾收集器工作时,
    在其他地方没有指向第一个key的引用,所以它被收集了,因此相对应的table中的入口也同时被移除了。
    可是,第二个key,仍然是占用活动的变量key,所以它不会被收集。--]]    
end

给table添加__mode元方法(__mode = "k"),就代表这个table的key是弱引用,一旦其他地方对于key值的引用取消了(设值为nil),那么这个table里的这个字段也会移除。

weak table 简单应用eg2:

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  

一个相当普遍的编程技术就是用空间换取时间,看上面的例子是服务器存储处理后的结果,一些命令一遍遍的重复执行,早晚有一天,它会挤爆服务器的内存。

一个weak表提供了这个问题的简单解决方案,如果这个结果表中有weak表,每次的垃圾循环都会移除当前时间内所有未被使用的结果(通常差不多是全部)。

在实际的代码过程中,我们不一定需要手动collectgarbage,因为该函数是在后台自动运行的,它有自己的运行周期和规律。

posted @ 2017-08-31 15:14  Mr. Ant  阅读(736)  评论(0编辑  收藏  举报