最近在弄一个avg类型的游戏,游戏操作比较简单,但是用到大量纹理,对内存优化就有一定要求,ps:包体大小和内存占用没有直接关系,下面是从网上搜的一些相关文章,有些步骤比较复杂或者需要改动比较大的,就不介绍了。
一、纹理缓存
网上关于cocos的纹理优化方面文章基本都是中文版的,这篇介绍的很详细,但是有些操作步骤不太好用,原出处是英文版的。
1.打印纹理占用情况,实时对比,cc.Director:getInstance():getTextureCache():getCachedTextureInfo(),每次优化完实时对比是否操作有效。
2.纹理占用的计算公式是:图片长度 * 图片宽度 * 单位像素占用的字节数, 所以16bit纹理代替32bit纹理能省一半,另外,图片大小和占用内存大小不
是一个概念, 比如一个2048*2048的png图片,采用32位颜色深度编码,那么它在磁盘上占用空间只有2MB,但是,如果变成纹理,它将消耗16MB的
内存。
3.cocos studio布局的文件里,纹理比较大的精灵最好放渲染层次底部。(这个就是按照纹理size从大到小的顺序加载纹理,不至于引起瞬
间加载的纹理爆表翻倍导致崩溃。)
4.比较常用的释放纹理的接口的是cc.Director:getInstance():getTextureCache():removeUnusedTextures(),这个是释放引用计数
为0的纹理, 还有removeTextureForKey是释放制定纹理,removeAllTextures是释放所有纹理缓存。这里要详细说明下,我采用的是在
场景退出的时候释放旧场景的的资源removeUnusedTextures,但是这里有个坑,旧场景onExit的时候纹理缓存的引用计数还不
为0,网上采用的是遍历引用计数+1,我嫌麻烦就把旧场景的所有节点递归遍历删除removeFromParent,再调用
removeUnusedTextures释放掉,可以getCachedTextureInfo打印一下,看下旧场景的纹理缓存是不是都释放掉了;其次,战斗场景
里纹理比较大的精灵删除时也要手动removeUnusedTextures。
5.发生纹理缓存自动删除,是纹理缓存占内存太大了,发生了自动释放,可以去源码里在纹理警告时忽略释放纹理缓存的操作。
6.使用位图字体的时候,位图字体的png也会加载到纹理缓存里,所以自制的字库不必要的字符不要加到位图文件里,其次,每一种字号会创建一种
缓存,最好和策划沟通好项目里一种字体的大小不要太多种。
二、lua 虚拟机。
打印lua内存占用的collectgarbage("count"),还是老规矩每次优化后对比一下占用。
我是在追踪google play后台,游戏崩溃和进程被杀的时候发现lua虚拟机好像出现了内存泄漏,应该是不注意的使用Lua造成,难点在于如何定位问题所在,之前用过
lua渲染树遍历的工具,由于我这个项目很多节点没命名就导致对比起来不太方便,又发现了一个开源工具关于 Lua 内存泄漏的检测,最后根据这个工具完美定位错误并解决。
具体的使用步骤上面那个连接里面很详细了,打印两次对比差异,我着重介绍下我这个项目里出现的lua使用不当:
1.最简单的局部变量或者方法忘记加了local。
2.加载的配置文件.txt或者.lua没释放掉,一个场景的配置在退出时最好释放掉旧的配置,这个是导致我这个项目内存泄漏的罪魁祸首之一。
3.lua的module在require之后就会被加载到全局变量里,在退出时最好 像这样package.loaded["app.view.BaseDlg"] = nil,释放掉在_G里的使用,罪魁祸首
之一。
4.自定义事件会造成不断的内存占用,这个最好要有自己的事件管理机制,不然lua内存占用会不断增加。