首页 > 代码库 > Chapter 17_1 弱引用table
Chapter 17_1 弱引用table
Lua采用了自动内存管理。所以不用担心新创建的对象需要的内存如何分配出来,也不用考虑对象不再被使用后怎样释放它们所占用的内存。
Lua实现了一个增量标记-扫描收集器。它使用这两个数字来控制垃圾收集循环:垃圾收集器间歇率 和 垃圾收集器步进倍率。
这两个数字都使用百分数为单位(例如:100在内部表示1)
前者表示控制收集器需要在开启新的循环前要等待多久,后者表示控制收集器运作速度相对于内存分配速度的倍率(不要设置为小于100,否则收集慢于分配)。
在Lua中,你可以用弱引用和终结器作为垃圾回收的机制。先来看弱引用table。
用户能用它来告诉Lua一个引用不应该阻碍一个对象的回收。弱引用就是一种会被垃圾收集器忽视的对象引用。
如果一个对象的所有引用都是弱引用,那么Lua就可以回收这个对象了,并且还可以以某种形式来删除这些弱引用本身。
Lua用 “弱引用table” 来实现 “弱引用”,一个弱引用table就是一个具有弱引用条目的table。
如果一个对象只被一个弱引用table所持有,那么最终Lua会回收这个对象。
通常,垃圾收集器不会回收一个可访问table中的作为key或value的对象。也就是说,这些key和value都是强引用,它们会阻止对其所引用对象的回收。
在一个弱引用table中,key和value是可以回收的。有3种弱引用table:
1》具有弱引用key的table
2》具有弱引用value的table
3》同时具有两种弱引用的table
不管哪种类型的table,当一个key或value被回收,那么它们所在的整个条目都会从table中删除。
一个table的弱引用类型是通过元表中的__mode字段来决定的。这个字段的值为一个字符串:
“k” :表示key是弱引用的
“v":表示value是弱引用的
“kv”:表示key和value都是弱引用
下面的代码演示了弱引用table的基本行为:
a = {}b = {__mode = "k" }setmetatable(a,b) -- now ‘a‘ 的key就是弱引用key = {} -- 创建第一个keya[key] = 1key = {} --创建第二个key,覆盖第一个key(没有了引用,将会被回收)a[key] = 2 --引用了变量keycollectgarbage() --强制进行一次垃圾回收for k , v in painrs(a) do print(v) -- 2end
Lua只会回收弱引用table中的对象。而像数字和布尔这样的值是不可回收的。
如果一个数字key所对应的value被回收了,那么整个条目都会从这个弱引用table中删除。
字符串在此显得有点特殊:看上去是可回收的,但是在有些方面与其他可回收对象不同。
其他对象,比如table和thread,都是显式创建的。
当Lua对表达式{}求值时,它就会创建一个新的table。同样地,当对“a” .. "b"求值 会创建一个新的字符串吗?
如果当前系统中已有一个字符串"ab",它会复用吗?还是创建一个新的字符串?
这些都无关紧要,它们都是实现的细节。从程序员角度看,字符串就是值,而非对象。
因此,字符串就像数字和布尔一样,不会从弱引用table中删除(除非和它相关联的值被回收)。
以上内容来自:《Lua程序设计第二版》和《Programming in Lua third edition 》
Chapter 17_1 弱引用table