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 = {}                      -- 创建第一个key
a[key] = 1
key = {}                      --创建第二个key,覆盖第一个key(没有了引用,将会被回收)
a[key] = 2                    --引用了变量key
collectgarbage()              --强制进行一次垃圾回收
for k , v in painrs(a) do 
    print(v)                  -- 2
end

Lua只会回收弱引用table中的对象。而像数字和布尔这样的值是不可回收的。

如果一个数字key所对应的value被回收了,那么整个条目都会从这个弱引用table中删除。

字符串在此显得有点特殊:看上去是可回收的,但是在有些方面与其他可回收对象不同。

其他对象,比如table和thread,都是显式创建的。

当Lua对表达式{}求值时,它就会创建一个新的table。同样地,当对“a” .. "b"求值 会创建一个新的字符串吗?

如果当前系统中已有一个字符串"ab",它会复用吗?还是创建一个新的字符串?

这些都无关紧要,它们都是实现的细节。从程序员角度看,字符串就是值,而非对象。

因此,字符串就像数字和布尔一样,不会从弱引用table中删除(除非和它相关联的值被回收)。

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

posted @ 2016-09-19 11:29  daiker  阅读(190)  评论(0编辑  收藏  举报