正在收集我的Lua对象?(Is my Lua object being collected?)

2019-10-17 15:45发布

警告:

我现在相信,问题是,luatraverse脚本这里解释是行不通的像广告,并没有找到一个对象的所有引用。 在我的例子,我发现那里的对象是被引用,从而防止其收藏,但不是由脚本报告。

因此,这个问题的基本前提是有点瑕疵。

该backgound:

我的工作提高脚本引擎在游戏Bitfighter 。 我不相信,内存被释放正确。 所以,我构建了一个测试,在下面的脚本的形式。

它打印userdatas的3列。 第1栏是用户数据我希望可以在其他地方使用,因此应由collectgarbage功能被破坏。 列2和3是对象,我不认为应该收捕,因为我保持手柄上他们。

问题:

在塔1中的用户数据从不改变,所以我怀疑它没有被收集(COLS 2和3表现为预期)。 为了进一步弄清情况,我使用中提到的luatraverse脚本这个问题 ,这似乎证实,只有一个参考obj100,这是存储在obj100本身。 我想只是运行countreferences(局部x = obj100)之前加入的分配,并如市场预期,countreferences报道的对象被引用两次。

问题:

1)我是不是正确解释这个输出,并obj100真的永远不会收集? 或者是有可能的是,相同的内存地址被一遍又一遍地重复使用?

2)是否有比luatraverse脚本更好的办法,看看有什么是引用一个特定的Lua对象?

编码:

 -- Every 2 seconds, find two objects with ids 100 and 200, and print their addrs
 -- No reference is kept for object 100, so its userdata might change over time
 -- Object 200 is held by objHolder, so its userdata should remain constant

 -- Obj200 should remain constant over time; obj100 can vary.  
 -- objHolder should be constant, obviously

 local ltraverse = require("luatraverse")


 function printIds()
    local obj100 = levelgen:findObjectById(100)
    local obj200 = levelgen:findObjectById(200)
    print("Obj 100:" .. tostring(obj100) .. " Obj 200:" .. 
           tostring(obj200) .. " Held:" .. tostring(objHolder))


    print(ltraverse.countreferences(obj100))

    obj100 = nil
    obj200 = nil

    collectgarbage()
 end

 function main()
    -- levelgen:findObjectById is a local game command that
    -- creates a userdata for an object
    local obj100 = levelgen:findObjectById(100)
    objHolder    = levelgen:findObjectById(200)     -- not local, global

    assert(obj100)
    assert(objHolder)

    print("Column 1 can vary; 2 and 3 should be constant")
    print("=============================================")

    print("Obj 100:" .. tostring(obj100) .. " Obj 200:" .. 
         tostring(objHolder) .. " Held:" .. tostring(objHolder))

    obj100 = nil

    -- Run a function every 2 seconds
    Timer:scheduleRepeating(printIds, 2000)
 end 

输出:

 Column 1 can vary; 2 and 3 should be constant
 =============================================
 Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280

 Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
 1
 Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
 1
 Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
 1
 Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
 1
 Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
 1
 ... and onward to infinity ...

Answer 1:

我不知道Bitfighter,但我相信你在这里测量错误的东西:

这条线将创建一个新的Lua用户数据基本对象指向真正的C ++对象(?):

local obj100 = levelgen:findObjectById(100)

后来下面一行将打印指向一个用户数据(withing Lua中引用的数量obj100 ,而不是实际的数据):

print(ltraverse.countreferences(obj100))

这将永远是1,因为你刚刚创建该对象的一个​​参考吧。

参考/ Lua的对象是最有可能的收集,你将看不到。 实际的用户数据(指针)始终是相同的,因为你请求相同的对象ID。 因此,该值必须不改变,除非相关联的数据被移动/通过一些其他的代码重新分配。

但最后,我要说这真的取决于levelgen:findObjectById()返回。 如果您尝试以下行,会发生什么?

local temp
local obj100 = temp = levelgen:findObjectById(100)


文章来源: Is my Lua object being collected?