Lua weak table


weak table的定义:

 (1)weak表是一个表,它拥有metatable,并且metatable定义了__mode字段;
 (2)weak表中的引用是弱引用(weak reference),弱引用不会导致对象的引用计数变化。换言之,如果一个对象只有弱引用指向它,那么gc会自动回收该对象的内存。
 (3)__mode字段可以取以下三个值:k、v、kv。k表示table.key是weak的,也就是table的keys能够被自动gc;v表示table.value是weak的,也就是table的values能被自动gc;kv就是二者的组合。任何情况下,只要key和value中的一个被gc,那么这个key-value pair就被从表中移除了( In any case, if either the key or the value is collected, the whole pair is removed from the table)。

  对于普通的强引用表,当你把对象放进表中的时候,就产生了一个引用,那么即使其他地方没有对表中元素的任何引用,gc也不会被回收这些对象。那么你的选择只有两种:手动释放表元素或者让它们常驻内存。


    在lua中任何对内存块的引用都会使引用数加1,但有一个例外:weak table,它对内存块的引用不会使引用增1 
看下面代码: 
---------------------------------------------------- 
a = {}; 
b = {};    
setmetatable(a, b); -- 设置a为weak table 
b.__mode = 'k'; 

key = {};    -- 增加"{}"内存块的一个引用key,引用数1 
a[key] = 1; -- weak table引用不增引数,所以"{}"内存块的引数还为1 
key = {}    -- 改变key指向新增的"{}"内存块,上面的"{}"内存块引数减一为0 
a[key] = 2     -- 如上上一样 

collectgarbage();   -- 调用GC,清掉weak表中没有引用的内存 

for k, v in pairs(a) do 
print(v);    -- 只输出一个2 
end 
---------------------------------------------------- 
如果a不是weak table而是普通的table,那么a将会对"{}"内存块的引数加1, 
去掉"b.__mode = 'k';"这句,你将会看到输出1和2。 
看最后一个例子: 
---------------------------------------------------- 
a = {} 
b = {} 
setmetatable(a, b)  -- 设置a为weak table 
b.__mode = "k" 


function test() 
    local key1 = {}; 
    a[key1] = 1; 
    local key2 = {}; 
    a[key2] = 2; 
end 
test(); -- 函数执行完后key1和key2它们指向的内存块引数都减一为0 

collectgarbage() -- 故全部都被清空 
for k, v in pairs(a) do 
print(v); -- 没有任何输出 
end 
---------------------------------------------------- 


设置弱引用为value

local testa = {}  
local mt = {__mode = 'kv'}  
setmetatable(testa,mt)  
  
tbl_key = {1,2,3}  
testa[1] = tbl_key  
tbl_key = {4,5,6}  
testa[2] = tbl_key  
  
--垃圾回收  
collectgarbage()  
  
local function PrintInfo()  
  
    for k, v in pairs(testa) do  
        for key, value in pairs(v) do  
            print(" value===", value)  
        end  
    end  
  
end  
  
print(testa[1])
print(testa[2])
PrintInfo()  


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值