参考链接:
https://www.cnblogs.com/ghl_carmack/p/6720500.html
https://zhuanlan.zhihu.com/p/41113505?edition=yidianzixun&utm_source=yidianzixun&yidian_docid=0JhF3poZ&yidian_s=&yidian_appid=
https://www.jianshu.com/p/3c853b6bf980
一.LuaObjectPool.cs(主要用于分配id)
1.PoolNode,存放id和对应的c#对象
2.int Add(object obj),保存c#对象并返回对应的id
3.object Remove(int pos),移除指定id对应的c#对象
4.复用性:
----------------------------初始化后
0-null(head),1-null
----------------------------Add2个节点(objA和objB)后
0-null(head),1-null,2-objA,3-objB
----------------------------Remove节点2(objA)后
2-null(head),1-null,0-null,3-objB
----------------------------Add1个节点(objC)后
0-null(head),1-null,0-objC,3-objB
----------------------------Remove节点2(objC)后
2-null(head),1-null,0-null,3-objB
----------------------------Add1个节点(objD)后
0-null(head),1-null,0-objD,3-objB
二.ObjectTranslator.cs(主要用于管理lua访问过的c#对象)
1.objectsBackMap,key为c#对象,value为id
三.c#到lua(以UnityEngine_TransformWrap.cs中的Find为例)
1.ToLua.Push(L, o),将找到的Transform进栈
2.如果之前objectsBackMap有缓存过该对象,则将该对象对应的id包装成userdata,并设置元表(Transform),进栈
3.否则,LuaObjectPool和ObjectTranslator会缓存该对象,再执行第2步后面的操作
四.lua到c#(以UnityEngine_TransformWrap.cs中的Find为例)
1.ToLua.CheckObject<UnityEngine.Transform>(L, 1),将userdata(即id)转换为c#对象
2.从栈中取出id后,转换为c#对象
五.c#对象的释放
lua层拿到的是一个int形式的userdata,由于lua对c#对象的引用,导致c#的gc机制无法释放掉对应的内存对象
对于lua层拿到的对象,会重写其__gc方法,当lua的gc执行时,会调用这个方法,从而释放掉ObjectTranslator这层缓存的c#对象
因此对于那些在lua层被访问过的对象,在不调用lua gc的情况下会一直驻留在ObjectTranslator这层
Collect定义:
RemoveObject定义:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?