Lua 自动进行内存的管理。程序只能创建对象(表,函数等),而没有执行删除对象的函数。通过使用垃圾收集技术,Lua 会自动删除那些失效的对象。任何在全局变量中声明的对象,都不是 Lua 认为的垃圾,即使你的程序中根本没有用到他们。这种情况下,不会回收,你应当自己处理它(你的程序),为这种对象赋 nil 值,防止他们锁住其他的空闲对象。
Weak 表是一种用来告诉 Lua 一个引用不应该防止对象被回收的机制。一个 weak 引用是指一个不被 Lua 认为是垃圾的对象的引用。如果一个对象所有的引用指向都是weak,对象将被收集,而那些 weak 引用将会被删除。Lua 通过 weak tables 来实现 weak引用。
表的 weak 性由他的 metatable 的__mode 域来指定的。
- a = {}
- b = {}
- setmetatable(a, b)
- b.__mode = "k" --表a 有一个weak keys
- key = {} -- create first key
- a[key] = 1
- key = {} -- create second key 覆盖第一个key(会被回收)
- a[key] = 2
- collectgarbage() -- forces a garbage collection cycle
- for k, v in pairs(a) do print(v) end
记忆函数:一个相当普遍的编程技术是用空间来换取时间。你可以通过记忆函数结果来进行优化,当你用同样的参数再次调用函数时,它可以自动返回记忆的结果。想像一下一个通用的服务器,接收包含 Lua 代码的字符串请求。每当它收到一个请求,它调用 loadstring 加载字符串,然后调用函数进行处理。然而,loadstring 是一个“巨大”的函数,一些命令在服务器中会频繁地使用不需要反复调用 loadstring 和后面接着的 closeconnection(),服务器可以通过使用一个辅助 table 来记忆 loadstring 的结果。在调用 loadstring 之前,服务器会在这个 table 中寻找这个字符串是否已经有了翻译好的结果。如果没有找到,那么(而且只是这个情况)服务器会调用 loadstring 并把这次的结果存入辅助 table。缺点(占用内存空间)
- --每一次新的请求产生新的颜色:
- function createRGB (r, g, b)
- return {red = r, green = g, blue = b}
- end
- --使用记忆函数:我们可以将同样的颜色结果存储在同一个 table 中。为了建立每一种颜色唯一的 key,
- local results = {} --辅助表
- setmetatable(results, {__mode = "v"})
- function createRGB (r, g, b) --记忆函数
- local key = r .. "-" .. g .. "-" .. b --key值
- if results[key] then return results[key] --存在直接返回结果
- else --不存在,在创建
- local newcolor = {red = r, green = g, blue = b}
- results[key] = newcolor
- return newcolor
- end
- end
关联对象属性:weak tables 的另一个重要的应用就是和对象的属性关联
对象属性和记忆:
- --使用 weak table 来将默认 vaules 和每一个 table 相联系
- 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
- --------------------------------------------------------------------
- --使用不同的 metatables 来保存不同的默认值
- 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