关于引擎内存泄露的分析与修改 - kyohwang/games GitHub Wiki
# 1. CocoStudio之LabelBMFont (泄漏次数最多)
我们游戏使用的编辑器是CocoStudio,里面有个控件是使用的FNT字体,解释时通过LabelBMFontReader设置生成的LabelBMFont对象的属性来使用FNT字体,这里会调用 LabelBMFont::setFntFile 来设置fnt字体,里面的实现会调用一个CCLabelBMFont对象的实例来渲染,这时候会执行CCLabelBMFont和CCSpriteBatchNode的初始化代码,而初始化代码中会new几个对象出来,这样造成的结果就是,每次读取fnt字体都会new几个对象,并且不会释放掉,造成了内存泄漏,修改方法如下图:
# 2. protobuf内存泄漏
直接上图吧,感觉作者是忘了释放c字符串,修改完已测试了一段时间,没有遇到问题。
# 3. CocoStudio之UI动画内存无法释放
CocoStudio的UI动画是把UI结点都保存在ActionManager中,通过ActionManager来执行UI动画,但是这个功能CocoStudio实现的是一个半成品,如果在动画播放过程中移除根节点,就会造成ActionManager中保存的部分结点无法释放掉,造成内存泄漏,我尝试修改了几个版本总是有不定时的崩溃问题,后来移植了cocos 3.14版本的关于UI动画的部分,增加了ActionManager:stopActionByName 方法,只要在移除UI结点之前调用停止动画,就可以保证不会造成内存泄漏。 具体代码,详见中华的引擎代码 ActionManager ActionObject ActionNode
# 4. 安卓下场景切换时无法释放旧场景 (影响最严重)
现在还无法定位是怎么产生的这个问题,所以暂时在替换旧场景的时候执行移除旧场景的所有子节点。
这种做法只能是最大量的移除场景内的结点,但是不能移除场景本身,尝试直接释放场景自身,但是会直接崩溃,这个问题会持续跟进,现在修改完这里之后效果非常显著,所以可以先这么修改。
# 5. CocosBuilder回调只内存泄漏 (影响较小)
CocosBuilder执行回调的时候,会回传参数,这里的参数为了不被释放掉被retain了,但是CocosBuilder会出现丢帧的情况,当回调这一帧丢了的时候,就无法回调lua代码,这时候回传参数自然也就无法释放了,目前这个问题还无法解决,尝试过统一来管理回传参数,但是我觉得应该是把丢帧问题解决才是正确做法,所以目前这个问题未解决。
6. 代码逻辑中的内存泄漏 (不容忽视)
我们现在使用的开发语言是lua,使用非常灵活,开发便捷,有利则有弊,我遇到的问题类型如下:
- 调用retain了,没有释放
- 多次调用创建事例的代码
- ccbi回调中移除自身,也会造成内存问题
补充: 5. CocosBuilder回调只内存泄漏 (影响较小) 问题已解决,详见 cocosbuilder回调
补充:问题5已解决,不再创建CCString对象,而是直接使用已有的对象进行数据传递。
补充:4 是lua代码中会有一个“onChangeScene”事件,对于场景进行了retain操作,已解决。
补充:
7. CCImage的init方法,初始化字符串的时候容易造成内存泄漏。
CCImage的initString方法,如果两次传入的字符串不同,其中有字符串就会返回false,然后调用break了,不会直接delete操作,造成内存泄漏。 详情请见代码。