Lua 弱引用table

本文转载于:http://www.benmutou.com/archives/1808

这次要介绍的内容比较少,就一个——弱引用table

1.无法超越人类智慧的智能——自动内存管理的缺陷

我们都知道,Lua是具备自动内存管理的,好吧,也许有些朋友不知道。

我们只管创建对象,无须删除对象(当然,对于不要的对象你需要设置一下nil值),Lua会自动删除那些被认为是垃圾的对象。

问题就出现在,什么对象才是垃圾对象,有些时候,我们很清楚某个对象是垃圾,但是,Lua却无法发现。

比如这样一个例子:

t = {};

    -- 使用一个table作为t的key值
    key1 = {name = "key1"};
    t[key1] = 1;
    key1 = nil;

    -- 又使用一个table作为t的key值
    key2 = {name = "key2"};
    t[key2] = 1;
    key2 = nil;

    -- 强制进行一次垃圾收集
    collectgarbage();

    for key, value in pairs(t) do
        print(key.name .. ":" .. value);
    end

这段代码有点复杂,智商低于250的可能会看不懂。

首先以一个table,叫做t。

然后创建一个新的table——key1,这个key1作为t的key值,给t新增了一个字段,赋值为1。

同样的,key2也作为t的一个key值。

接着,调用了collectgarbage函数,可以不管它,我们只要知道,它会让lua进行一次垃圾回收

最后输出t的所有字段,输出结果如下:

[LUA-print] key1:1
[LUA-print] key2:1

这很符合常理,也在我们的预计当中,虽然我们在给t赋值之后,key1和key2都赋值为nil了。

但是,已经添加到table中的key值是不会因此而被当做垃圾的。

换句话说,key1本身已经是nil值,但它曾经所指向的内容依然存放在t中。key2也是一样的情况。

所以我们最后还是能输出key1和key2的name字段。

2.颠覆你的认知——弱引用table

刚刚举例的只是正常情况,那么,如果我们把某个table作为另一个table的key值后,希望当table设为nil值时,另一个table的那一条字段也被删除。

应该如何实现?

这时候就要用到弱引用table了,弱引用table的实现也是利用了元表。

我们来看看下面的代码,和之前几乎一样,只是加了一句代码:

t = {};

    -- 给t设置一个元表,增加__mode元方法,赋值为“k”
    setmetatable(t, {__mode = "k"});

    -- 使用一个table作为t的key值
    key1 = {name = "key1"};
    t[key1] = 1;
    key1 = nil;

    -- 又使用一个table作为t的key值
    key2 = {name = "key2"};
    t[key2] = 1;
    key2 = nil;

    -- 强制进行一次垃圾收集
    collectgarbage();

    for key, value in pairs(t) do
        print(key.name .. ":" .. value);
    end

留意,在t被创建后,立刻给它设置了元表,元表里有一个__mode字段,赋值为”k”字符串。

如果这个时候大家运行代码,会发现什么都没有输出,因为,t的所有字段都不存在了。

这就是弱引用table的其中一种,给table添加__mode元方法,如果这个元方法的值包含了字符串”k”,就代表这个table的key都是弱引用的。

一旦其他地方对于key值的引用取消了(设置为nil),那么,这个table里的这个字段也会被删除。

通俗地说,因为t的key被设置为弱引用,所以,执行t[key1] = 1后,t中确实存在这个字段。

随后,又执行了key1 = nil,此时,除了t本身以外,就没有任何地方对key1保持引用,所以t的key1字段也会被删除。

3.三种形式的弱引用

对于弱引用table,其实有三种形式:

1)key值弱引用,也就是刚刚说到的情况,只要其他地方没有对key值引用,那么,table自身的这个字段也会被删除。设置方法:setmetatable(t, {__mode = “k”});

2)value值弱引用,情况类似,只要其他地方没有对value值引用,那么,table的这个value所在的字段也会被删除。设置方法:setmetatable(t, {__mode = “v”});

3)key和value弱引用,规则一样,但是key和value都同时生效,任意一个起作用时都会导致table的字段被删除。设置方法:setmetatable(t, {__mode = “kv”});

当然,这里所说的被删除,是指在Lua执行垃圾回收的时候,并不一定是立刻生效的。

我们刚刚只是为了测试,而强制执行了垃圾回收

4.结束

好了,这次的内容比较少,其实书上有蛮多关于弱引用的例子的。

关于Lua的最基础部分,到这里算是结束了。

后面的内容是一些库的介绍,以及更深入的一些内容(C和Lua间调用、自定义类型、线程、内存管理)。

接下来可能会放缓文章更新速度,因为好多库的介绍,不知道有没有必要用文章记录下来。

可能而已~

时间: 2024-10-07 18:29:09

Lua 弱引用table的相关文章

Lua弱引用table

弱引用table 与python等脚本语言类似地,Lua也采用了自动内存管理(Garbage Collection),一个程序只需创建对象,而无需删除对象.通过使用垃圾收集机制,Lua会自动删除过期对象.垃圾回收机制可以将程序员从C语言中常出现的内存泄漏.引用无效指针等底层bug中解放出来. 我们知道Python的垃圾回收机制使用了引用计数算法,当指向一个对象的所有名字都失效(超出生存期或程序员显式del了)了,会将该对象占用的内存回收.但对于循环引用是一个特例,垃圾收集器通常无法识别,这样会导

(转载)【笨木头Lua专栏】基础补充22:弱引用table

这次要介绍的内容比较少,就一个--弱引用table 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址:http://www.benmutou.com/archives/1808 文章来源:笨木头与游戏开发 1.无法超越人类智慧的智能--自动内存管理的缺陷 我们都知道,Lua是具备自动内存管理的,好吧,也许有些朋友不知道. 我们只管创建对象,无须删除对象(当然,对于不要的对象你需要设置一下nil值),Lua会自动删除那些被认为是垃圾的对象. 问题就出现在,什么对象才是垃圾对象,有些时候

Chapter 17_1 弱引用table

Lua采用了自动内存管理.所以不用担心新创建的对象需要的内存如何分配出来,也不用考虑对象不再被使用后怎样释放它们所占用的内存. Lua实现了一个增量标记-扫描收集器.它使用这两个数字来控制垃圾收集循环:垃圾收集器间歇率 和 垃圾收集器步进倍率. 这两个数字都使用百分数为单位(例如:100在内部表示1) 前者表示控制收集器需要在开启新的循环前要等待多久,后者表示控制收集器运作速度相对于内存分配速度的倍率(不要设置为小于100,否则收集慢于分配). 在Lua中,你可以用弱引用和终结器作为垃圾回收的机

Lua程序设计 第17章 弱引用笔记

鉴于之前我对lua的评价,在此需要修改了一下我的言论:游戏开发语言工作中,最成熟的客户端开发组合:C/C++.Lua/C#.assembly汇编.C/C++系列用于完成游戏引擎框架,汇编用于优化,Lua负责游戏逻辑.在全局上满足了性能.可读性.变化性的需求.因为我选的是引擎方向,实际上只能吃透C/C++系列我才可能获得引擎 职位.另外推荐一本书<游戏引擎框架>-叶劲峰翻译的那本,并没有csdn某人读后感言"引擎水真深"的感觉.这本书写得好,可是那个废人却在叶劲峰的专访中说这

lua弱表引用

1.普通垃圾回收 --lua弱表,主要是删除key或者value是table的一种元方法 --元表里的__mode字段包含k或者v:k表示key为弱引用:v表示value为弱引用 local testa = {} tbl_key = {} testa[tbl_key] = 1 tbl_key = {} testa[tbl_key] = 2 --垃圾回收 collectgarbage() local function PrintInfo() for k, v in pairs(testa) do

lua的弱弱引用表

lua有GC,细节无需太关注,知道些基本的就行,能local就一定不要global: 还有在数组里的对象,除非显式=nil,否则很难回收: 不过可以用弱引用表来告诉GC.外部引用为0,就不要管我,请del it. weak table是通过元表实现,元表里的__mode字段包含k或者v:k表示key为弱引用:v表示value为弱引用. 1.首先看一个普通的例子: a = {} key = {} a[key] = 1 key = {} a[key]=2 collectgarbage() for k

lua中对象的弱引用

几次编写lua时.总是有同事遇到A中对象已经释放了.但B对象中A对象的值不是为空的. Lua的gc和Java的类似.只有当对象没有被引用时候才会释放这块内存.要想实现A释放了B中A的值也释放了这时候需要用到弱引用. setmetatable(t,{__mode="k"}); __mode 的值可以为"k","v","kv" ~ ~第一段代码中可以看到内存中是有一个[key]保存了一个table.虽然b=nil了但是t中还是存在

OC对象之旅 weak弱引用实现分析

Runtime源码分析带你了解OC实现过程.其中参考了大量的大神的代码以及文献里面也有个人的见解欢迎拍砖欢迎交流. 两种常见使用场景 /// weak属性@interface XX : [email protected](nonatomic,weak) Type* weakPtr;@end/// 代码块中使用{    /// 使用__weak     __weak Type* weakPtr = [[SomeObject alloc] init]; } 根据调试信息发现两者的区别是 第一种进入到

Torch-RNN运行过程中的坑 [1](读取Lua非空table,size为0)

0.踩坑背景 执行Torch-RNN的时候,在LanguageModel.lua中的encode_string函数中,对start_text的各个character进行id映射编码,实现功能类似"北京天安门"-->"5 10 88 32 111",方便后面的计算. 这个函数会利用一个全局的类似HashMap的table,hashmap中的key是character(char),value是id(int),涉及到一个从hashmap中按照key取值的操作,代码如