理解lua中Weak Table

转载 2013年12月06日 09:02:12

[转自 http://blog.csdn.net/flowshell/article/details/6234233 ]


如果你对lus语言的中weak table不明白的话,那这篇文章应该对你有帮助。 

所有脚本语言几乎都有垃圾回收器(GC),当然lua也有。 

不明白GC不要紧,下面让我来解释: 
这一切要先从现代编程语言的鼻祖 — C语言开始。 

如果你在C中要使用变量,可以这样定义变量,如: 
---------------------------------------------------- 
void hello(){ 
int a = 0; // 局部变量声明 

---------------------------------------------------- 
局部变量a的生与死是已经确定的,就是{括号和}括号之间。 
这样会很安全,因为函数在执行完后会清栈(清理变量),所以你不用去考虑变量的生与死,但,它不够灵活,因为它的作用域被界限了,它只能在这个函数里被使用。 

换种手段,定义全局变量,如下: 
---------------------------------------------------- 
static int a = 0;// 全局变量声明 

void hello1(){ 
a = 1; 

void hello2(){ 
a = 2; 

---------------------------------------------------- 
很显然,这样很灵活,到哪里都可以使用。 
不过自从它生之后,就不会结束了,直到程序关闭时它才结束。 
这意味着,程序运行期间无论如何它都将存在。 
你面对的将是一个永恒的变量,如果你定义了10,100,1000个...那将会是一堆...(僵尸?) 

这样都很不好,你无法控制变量的生与死,无法达到灵活处理变量生与死的目的。 
想亲手控制变量的生与死?C便提供了一个函数实现你的梦想 - malloc,如下: 
---------------------------------------------------- 
int* p = (int *)malloc(sizeof(int)); // 手动创建 — 生 

这样p便存储了申请过来的这块内存首地址,现在就可以使用了,如下: 

*p = 1; 

当你不再使用这块内存的时候,那你就使用free函数释放(清理)它,否则它将一直存在。 

free(p);   // 手动释放 — 死 
---------------------------------------------------- 
如果你不这样做,那内存将会增长直到程序崩溃(世界就乱了)。 

这样子看,第3个方法很好很灵活,但是一旦你定义了这种变量多了,你将成为上帝 — 你必须管理每个变量的生与死,哪怕是1,10,100,1000。一个都不能漏,否则世界的平衡就乱了(有人不死啦),换句话你程序也将挂了。 

这样看来很显然不是每个人都喜欢或者能做上帝,在这样的情况下,有一个东西横空出世了 — GC! 
它就是这个问题的救世主,下面详细介绍: 

GC - Garbage Collectoion - 垃圾回收器 

它的作用就是变量你随意定义,手尾我来跟,你只须定义变量的生,变量的死由我来负责。 
那你不经地问:那你怎么知道这个变量我不用了? 

那这个问题就比较复杂,目前GC的实现有好多种,敝人只知道引数GC,下面就用lua来说说它。 
先说明一点:在脚本语言中变量的声明都是使用上面说的第三种方法 - malloc来手动创建内存块。 

lua代码: 
---------------------------------------------------- 
function test() 
local a = {x=1};   -- GC将给"{x=1}"手动创建的这块内存块增加一个引用 - b,引用数为1 
end 

test(); -- 函数执行完后清栈,局部变量a被清掉,GC将给"{x=1}"这块内存将减少一个引用,引用数为0,引用数为0时GC就清理掉"{x=1}"这块内存。 

print(a);   -- nil 
-------------------------------------- 
再看下面: 
---------------------------------------------------- 
b = 0;   -- 外部变量 
function test() 
local a = {x=1}; 
b = a;   -- GC将给"{x=1}"这块内存再加一个引用 - a,引用数为2 
end 
test(); -- 函数执行完后清栈,"{x=1}"这块内存引用数减1还剩1,那这块内存块不用清理。 

print(b); -- table: 003BAAD8 
---------------------------------------------------- 

上面的例子你应该大致清楚GC的工作原理了吧,下面看最后此文的关键:lua - weak table 

在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) 
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 
---------------------------------------------------- 
以上是我自己对gc的理解(没去查资料^_^),仅供参考... 

后语:GC虽然是救世主,但不是万能的救世主,在回收变量中存在一些问题,如效率、循环引用等等需要去关注...

 

本文转自:http://hi.baidu.com/xuyuqiang/blog/item/29aa10f2529cba14b17ec51b.html


理解lua中Weak Table

如果你对lus语言的中weak table不明白的话,那这篇文章应该对你有帮助。 所有脚本语言几乎都有垃圾回收器(GC),当然lua也有。 不明白GC不要紧,下面让我来解释: 这一切要先从...

Lua内存泄露检测原理和weak_table弱引用

lua内存泄露 首先第一点,lua中的内存泄露和我们所说的c/c++中的内存泄露本质上是不一样的。 lua中有垃圾回收机制(GC),所以理论上是不会有内存泄露的。当它进行GC的时候,会从根部开始扫描所...

lua中的weak table及内存回收collectgarbage

弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的。弱表的定义是:Aweak table is a table whose elements are weak refe...

lua weak table (转)

如果你对lus语言的中weak table不明白的话,那这篇文章应该对你有帮助。 所有脚本语言几乎都有垃圾回收器(GC),当然lua也有。 不明白GC不要紧,下面让我来解释: 这一...

Lua中的weak表——weak table

弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的。弱表的定义是:A weak table is a table whose elements are weak ref...

iOS管理对象内存的数据结构以及操作算法--SideTables、RefcountMap、weak_table_t

第一次写文章语言表达能力太差。如果有哪里表达的不够清晰可以直接评论回复我,我来加以修改。这篇文章力求脱离语言的特性,咱们多讲结构和算法。即使你不懂iOS开发,不懂Objective-C语言也可以看这篇...

Lua_第16 章 Weak 表

Weak 表是一种用来告诉 Lua 一个引用不应该防止对象被回收的机制。一个 weak引 用是指一个不被 Lua 认为是垃圾的对象的引用。如果一个对象所有的引用指向都是 weak,对象将被收集,而那些...

快速掌握Lua 5.3 —— "Weak Tables"以及数学库

Q:“引用”和“引用计数”? -------------- A:“引用”既为对象的名字。比如`a = {}`,名叫`a`的变量存储的值是一个"table","table"的名字是`a`;同时还可以说变...

excel 转lua table

  • 2016年04月29日 18:15
  • 2KB
  • 下载

lua库函数整合。math table string

  • 2016年03月25日 15:07
  • 148KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:理解lua中Weak Table
举报原因:
原因补充:

(最多只允许输入30个字)