警告:
我现在确信问题在于这里解释的 luatraverse 脚本不能像宣传的那样工作,并且没有找到对对象的所有引用。在我的示例中,我找到了对象被引用的位置,从而阻止了它的收集,但脚本没有报告这一点。
因此,这个问题的基本前提有些缺陷。
背景:
我正在努力增强游戏Bitfighter中的脚本引擎。我不相信内存正在被正确释放。所以我以下面脚本的形式构建了一个测试。
它打印 3 列用户数据。第 1 列是我希望在其他任何地方都不会使用的用户数据,因此应该被 collectgarbage 函数销毁。第 2 列和第 3 列是我认为不应该收集的对象,因为我正在处理它们。
问题:
第 1 列中的用户数据永远不会改变,所以我怀疑它没有被收集(第 2 列和第 3 列的行为符合预期)。为了进一步澄清情况,我使用了这个问题中提到的 luatraverse 脚本,这似乎证实了对 obj100 的引用只有一个,即存储在 obj100 本身中的那个。我尝试在运行 countreferences (local 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 ...