unity-tolua之释放引用实测
unity-tolua之释放引用实测, 主要是验证是否能够解开 lua 与 csharp 之间的引用, 进而被对应 gc 回收.
前篇
目的是测试 csharp 中的 lua 相关导出变量在不 Dispose 的情况下是否会解引用, 进而被 gc.
相关测试代码
csharp
1
2
3
4
5
6
7
8
9
10public class CDog : MonoBehaviour {
public LuaFunction luaCellCreateFn;
void OnDestroy() {
if (luaCellCreateFn != null) {
luaCellCreateFn.Dispose(); // 主要是测试 Dispose
luaCellCreateFn = null;
}
}
}lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54-- 类定义
local CGm = class()
CGm.__name = "CGm"
function CGm.Init(self)
end
return CGm
-- lua 对象被回收会调用这个函数, obj 是实例对象, 这个代码就不贴那么细了
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() -- 创建 CGm 实例
local dog = GameMgr.Ins:AddComponent("CDog")
dog.luaCellCreateFn = function() -- 绑定 lua 方法到 csharp 中
testIns:Init() -- 引用住 testIns
end
end
---
### 确定实例对象及方法都是引用住的
1. 执行 `_test` 方法, 会往 go 上挂一个 `CDog` 实例组件, 同时 绑定了 `luaCellCreateFn` 方法, `luaCellCreateFn` 方法右引用住了 `testIns` 实例
2. 触发 lua gc 几次
![](https://pic04.wilker.cn/20211211172815-1.webp)
没有发现 `testIns` 实例被回收的日志, 这是正确的, 因为被引用住了
---
### 不 Dispose LuaFunction
1. 注释掉 csharp 中 `CDog` 的 `OnDestroy` 方法中的 `luaCellCreateFn.Dispose();` 代码
2. 在 lua 中销毁 dog 实例
```json
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 实例
1
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)