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,因为该函数是在后台自动运行的,它有自己的运行周期和规律。