警告:
問題は、ここで説明した luatraverse スクリプトが宣伝どおりに機能せず、オブジェクトへのすべての参照が見つからないことにあると確信しています。私の例では、オブジェクトが参照されている場所を見つけたため、そのコレクションが妨げられましたが、スクリプトによって報告されませんでした。
したがって、この質問の基本的な前提には多少の欠陥があります。
背景:
ゲームBitfighterのスクリプト エンジンの強化に取り組んでいます。メモリが適切に解放されているとは確信していません。そこで、以下のスクリプトの形式でテストを作成しました。
3 列のユーザーデータを出力します。列 1 は、他では使用されないと予想されるユーザーデータであるため、collectgarbage 関数によって破棄する必要があります。2 列目と 3 列目は収集する必要がないと思われるオブジェクトです。
問題:
列 1 のユーザーデータは変化しないため、収集されていないと思われます (列 2 と 3 は期待どおりに動作します)。状況をさらに明確にするために、この問題で言及されている luatraverse スクリプトを使用しています。これは、obj100 自体に格納されている obj100 への参照が 1 つしかないことを確認しているようです。countreferences (local x = obj100) を実行する直前に割り当てを追加しようとしましたが、予想どおり、countreferences はオブジェクトが 2 回参照されていることを報告しました。
質問:
1) この出力を正しく解釈していますか? obj100 は本当に収集されませんか? または、同じメモリアドレスが何度も再利用されている可能性はありますか?
2) 特定の Lua オブジェクトを参照しているものを確認する luatraverse スクリプトよりも良い方法はありますか?
コード:
-- 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 ...