title: unity-tolua之释放引用实测 categories: Unity3d tags: [unity, tolua] date: 2021-12-11 17:08:58 comments: false mathjax: true toc: true
unity-tolua之释放引用实测, 主要是验证是否能够解开 lua 与 csharp 之间的引用, 进而被对应 gc 回收.
前篇
目的是测试 csharp 中的 lua 相关导出变量在不 Dispose 的情况下是否会解引用, 进而被 gc.
相关测试代码
-
csharp public class CDog : MonoBehaviour {
public LuaFunction luaCellCreateFn;
void OnDestroy() {
if (luaCellCreateFn != null) {
luaCellCreateFn.Dispose();
luaCellCreateFn = null;
}
}
}
-
lua
local CGm = class()
CGm.__name = "CGm"
function CGm.Init(self)
end
return CGm
function _luaObjGc(obj)
local type_id = obj.__name
if type_id then
gLog("--- _luaObjGc, name: {0}", type_id)
end
end
function _test()
local testIns = require("gm"):New()
local dog = GameMgr.Ins:AddComponent("CDog")
dog.luaCellCreateFn = function()
testIns:Init()
end
end
确定实例对象及方法都是引用住的
-
执行 _test 方法, 会往 go 上挂一个 CDog 实例组件, 同时 绑定了 luaCellCreateFn 方法, luaCellCreateFn 方法右引用住了 testIns 实例 -
触发 lua gc 几次 没有发现 testIns 实例被回收的日志, 这是正确的, 因为被引用住了
不 Dispose LuaFunction
-
注释掉 csharp 中 CDog 的 OnDestroy 方法中的 luaCellCreateFn.Dispose(); 代码 -
在 lua 中销毁 dog 实例 GameObject.Destroy(dog)
-
触发 lua gc 几次 (不要太多次, 不要触发到 csharp 的 gc) 发现了其他 lua 实例被回收的日志, 但没有发现 testIns 实例被回收的日志 -
触发 csharp gc 几次 再触发 lua gc 几次 发现 testIns 实例被回收的日志 原因是因为 csharp 中 CDog 实例被 gc 后, 才会调用到 tolua 框架的 析构函数 进行解引用, 解引用完后绑定到 luaCellCreateFn 的 lua 方法才被释放, 然后进一步回收 testIns 实例
主动 Dispose LuaFunction
-
打开 csharp 中 CDog 的 OnDestroy 方法中的 luaCellCreateFn.Dispose(); 代码 -
在 lua 中销毁 dog 实例 GameObject.Destroy(dog)
-
触发 lua gc 几次 发现 testIns 实例被回收的日志, 而且还在其他 lua 实例被回收之前 原因是因为 CDog 的 OnDestroy 方法中的 luaCellCreateFn.Dispose(); 代码, 主动解开了 lua 中绑定的 luaCellCreateFn 方法引用, 然 lua gc 时就可以立马释放 luaCellCreateFn 方法 及 testIns 实例
结论
在 csharp 中不主动 Dispose lua 方法/table 都是没问题的, 只是被回收的时间会比较长
如果主动 Dispose , 就能及时回收 lua 实例.
by the way, 养成良好习惯, 在不使用时都主动置空 (lua 置为 nil, csharp 置为 null)
|