LUA GC 简单测试

function table.count(t)
    if type(t) ~= "table" then
        assert(false)
        return
    end

    local n = 0
    for k, _ in pairs(t) do
        n = n + 1
    end
    return n
end

local t = {
    x1 = "hello",
    x2 = "world",
    [1] = "x1111",
}

print(table.count(t))
t.x1 = nil

collectgarbage()

print(table.count(t))

 弱引用的GC:LUA和C#一样,也分值类型:数值,BOOL; 引用类型:LUA表,线程,协程,function, userdata。

弱引用最好只用在引用类型上,若用在数值类型及非构造类型,如数值,字符串等则会出现手动GC不能起作用的现象。

 1 weakTable = {}
 2 weakTable[1] = function() print("i am the first element") end
 3 weakTable[2] = function() print("i am the second element") end
 4 weakTable[3] = {1, 2, 3}
 5 weakTable[4] = 12
 6 weakTable[5] = {1, 2, 32}
 7 
 8 setmetatable(weakTable, {__mode = "v"})        -- 设置为弱表
 9 
10 print(table.getn(weakTable))
11 
12 ele = weakTable[1]
13 collectgarbage()
14 print(table.getn(weakTable))
15 
16 ele = nil
17 weakTable[2] = nil
18 weakTable[3] = nil
19 weakTable[4] = nil --若将这句注释掉,则会发现GC出问题了:只有weakTable[1]被GC了
20 
21 collectgarbage()
22 print(table.getn(weakTable))

 

 

弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的。弱表的定义是:A weak table is a table whose elements are weak references,元素为弱引用的表就叫弱表。有弱引用那么也就有强引用,有引用那么也就有非引用。我们先要厘这些基本概念:变量、值、类型、对象。

  (1)变量与值:Lua是一个dynamically typed language,也就是说在Lua中,变量没有类型,它可以是任何东西,而值有类型,所以Lua中没有变量类型定义这种东西。另外,Lua中所有的值都是第一类值(first-class values)。

  (2)Lua有8种基本类型:nil、boolean、number、string、function、userdata、thread、table。其中Nil就是nil变量的类型,nil的主要用途就是一个所有类型之外的类型,用于区别其他7中基本类型。

  (3)对象objects:Tables、functins、threads、userdata。对于这几种值类型,其变量皆为引用类型(变量本身不存储类型数据,而是指向它们)。赋值、参数传递、函数返回等都操作的是这些值的引用,并不产生任何copy行为。

   

  Lua的垃圾回收机制:gc是很多语言的常见机制,让程序员拜托复杂易出错的内存管理。

  定义:Lua manages memory automatically by running a garbage collector to collect all dead objects (that is, objects that are no longer accessible from Lua). 

  三点理解:(1)gc自动运行,也可以手动调用;(2)自动收集的目标是引用计数为0的对象;(3)dead objects:不能访问到的对象,没有引用指向它了,当然就是访问不到的了,也就等同于垃圾内存了。

 

  weak table的定义:

  (1)weak表是一个表,它拥有metatable,并且metatable定义了__mode字段;

  (2)weak表中的引用是弱引用(weak reference),弱引用不会导致对象的引用计数变化。换言之,如果一个对象只有弱引用指向它,那么gc会自动回收该对象的内存。

  (3)__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)。

posted @ 2016-10-27 12:52  时空观察者9号  阅读(408)  评论(0编辑  收藏  举报