在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Lua垃圾收集策略Lua自动进行内存的管理。程序只能创建对象,而没有执行删除对象的函数。通过使用垃圾收集技术,Lua会自动删除那些失效的对象,也就是引用为0 的对象。但是呢?有些对象,引用没有指向它,就没办法引用到他,就相当于没法回收的垃圾内存。 一个典型的例子就是堆栈:有一个数组和指向栈顶的索引构成。认为数组中有效的只是在顶端的那一部分,但Lua不那么认为。如果你通过简单的出栈操作提取一个数组元素,那么数组对象的其他部分对Lua来说仍然是有效的。同样的,任何在全局变量中声明的对象,都不是Lua认为的垃圾,即使你的程序中根本没有用到他们。这两种情况下,你应当自己处理,为这种对象赋nil值,防止他们锁住其他的空闲对象。 看下面的例子:
上面的代码中输出为1 , 2, 第二次采用同样的键值覆盖第一次的数据,但在collectgarbage()并没有是释放第一次引用的数据。除了遍历就不能通过其他途径获取到这个数据了,但对于对象而言,存放在数组中就相当于过一个强引用,Gc当然不会回收了。 Weak Table我觉得英文的解释更清晰一点,《Lua程序设计》中文描述实在理解不了。还是看下下面的描述吧:
最重要的点是:如果一个对象所有的引用都是weak,对象将被收集,而那些weak引用将会被删除。,如果上面的数组是一个weak table,那第一次数据被覆盖后,只存在weak 引用指向数组对象,所以在collectgarbage时会被当做垃圾收集。 Weak Table方式定义Weak Table方拥有metatable,元方法 _mode字段定义了指定weak性,__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)。
a 变为weak table之后,第二个赋值语句key={}覆盖了第一个key的值。当垃圾收集器工作时,在其他地方没有指向第一个key的引用,所以它被收集了,因此相对应的table中的入口也同时被移除了。可是,第二个key,仍然是占用活动的变量key,所以它不会被收集。 需要注意的:只有对象才可以从一个weak table中被收集。比如数字和布尔值类型的值以及字符串,都是不会被收集的。不过可以将value设置为weak refence,value在没有引用的时候一起将表中对应key-value销毁。 应用案例1-- 记忆函数
想像一下一个通用的服务器,接收包含Lua代码的字符串请求。每当它收到一个请求,它调用loadstring加载字符串,然后调用函数进行处理。然而,loadstring是一个“巨大”的函数,一些命令在服务器中会频繁地使用。不需要反复调用loadstring和后面接着的closeconnection(),服务器可以通过使用一个辅助table来记忆loadstring的结果。在调用loadstring之前,服务器会在这个table中寻找这个字符串是否已经有了翻译好的结果。如果没有找到,那么(而且只是这个情况)服务器会调用loadstring并把这次的结果存入辅助table。 带有默认的表
结束语看完Lua交互APi之后为什么要回来看weak表的问题呢?有可能带有GC的语言中都会存在weak ref这样一个概念,至少是解决一种情况下垃圾内存的一种方式。OK ,在Ulua的实现中,C#对象和Lua之间也是通过weaktable建立联系,[C++ Tolua也是采用类似的实现方式][2]。 [2]:http://www.luvfight.me/lua-cpp-object-life-time/ “Cocos2d-x-Lua对象生命周期管理” |
请发表评论