unity开发中lua的一些小问题

打包前在做例行内存检测,发现了一些很值得说的点。当lua层直接穿透到C#层获取组件调用时,类似toggle,slider都有一个onvalueChange的属性,这个属性的监听是不会随着组件本身的销毁和解除引用而被GC的,需要手动removeListener和invoke,不然就会内存泄漏。

对于复合应用类组件,释放组件的时候要遍历内部二次加载的物体(通常是因为需要动态加载导致),先销毁内部物体,释放内部引用再对上层组件进行销毁释放。其实内存泄漏虽然后果很可怕,但是解决问题反而简单直白的多,只要你理清unity和lua的双GC系统,搞懂unity,lua的对象引用和资源加载机制,然后根据载入流程反向逐步释放,每一步都检查自己有没有遗漏就行。

简单来说就是lua虚拟机持有一张对ui进行管理的表结构数据(UI管理表),这个表里会对mono虚拟机直接持有的ui控件进行引用获取,然后在lua层进行操作。mono虚拟机在运行的时候会引用这张表,通过获取表内的数据,对自己持有的UI对象进行直接操作。知道了这个步骤之后,剩下的操作就变得理所当然了起来。首先调用C#这边的destroy方法去清除unity对资源的内存,然后lua端解除对ui管理表的所有引用.接下来就是C#层调用dipose解除uitable的引用。这一步完成的时候,lua层应该及时调用GC方法释放对unity对象池内对象的引用。到了这一步,可以说lua层已经被释放完毕,接下来就是纯粹的C#内释放过程。置空对象后释放引用即可。

我个人觉得泄漏的问题,只要你够仔细,能够逐步排查,最后都能得到一个比较满意的表现。真正的难点在于性能优化。既然叫优化,说明这是一个非常依赖个人水平的操作,你的水平直接决定了整个优化的效果。要做好优化,重点就是要对每一个常见操作在lua和c#内的操作消耗了然于心。

首先,诸如获取某个物体的子物体.本地位置.gameObject属性之类的,在C#层面就是一个非常简单的一步调用,可是一旦放在Lua层,lua本身的字符串连接啊,传递啊就有不小的性能问题,而且lua会把传进去的Vector3当成table或者userdata处理。因此,在lua穿透到C#层调用unity控件的时候,没有特殊情况千万不要直接把字符串传来传去的去拿组件,直接在C#层把要用的UI类型注册到一个List里去,然后用luatable注册到一个专用的ui操作表里,在调组件的时候直接lua一步传递给C#层,去C#层进行后续的操作。更多复杂的优化操作强烈建议大家阅读lua作者Roberto Ierusalimschy写的lua性能优化

猜你喜欢

转载自www.cnblogs.com/SnowCoder/p/13167022.html