首页 > 学院 > 开发设计 > 正文

内存问题

2019-11-09 18:31:57
字体:
来源:转载
供稿:网友

前段时间,我们公司开发的游戏进行了第一次测试, 结果在android平台上, 由于内存消耗过大,引起了很多崩溃的问题。 我做游戏的时候,内存过大的问题, 一直没有引起过我的重视,现在想想,主要是没有碰到过内存占有量太大引起崩溃的问题,那为什么这一次, 这个问题这么的突出呢, 因为这一次我们的游戏类型是一款挂机游戏,也就是战斗部分,是永远存在的。问题就来了,战斗中会有大量的怪物,技能特效,都加载内存中,而切换界面的时候,战斗是没有释放的,之前的游戏,当切换到非战斗界面,战斗就会被释放,自然不会有很大的内存问题,其实出现这个问题,也是有好处的,至少让我更加重视内存消耗了。 既然出现了这个问题,那么接下来就是如何解决。 1 场景切换的时候,调用引擎函数removeUnusedTextures() 来释放那些引用计数为1的图片缓存资源,虽然说缓存是为了性能更快,但是当为了追求性能而引起别的问题,那么将是得不偿失。 2 使用了上面的方法后,发现在一些低端机,还是会出现内存不足,那么需要进一步优化。 3 我们ui工程用的是cocostudio制作的,当时每个界面对应着一张大图,跟踪引擎代码,发现引擎加载大图的时候,首先会把这张大图放到系统的纹理缓存内,和普通的小图一样。所以,每一张texturePacker打包出来的大图,在引擎的纹理缓存内都对应着一份缓存,而我们的打包出来的大图,一般都是比较大的资源,所以可以清楚这部分数据。接着引擎会遍历该大图内所有的小图,生成精灵帧,存放到精灵帧缓存内,在这里看到,注意到,加载一个一个的精灵帧的时候,也会有同名的处理, 也就是说,如果两张大图内包含相同名字的小图,那么只认最开始加载的那个小图,后面发现同名,会直接跳过。在这里,又发现了一个优化点,就是当释放了某个界面的时候,也可以删除该界面对应的精灵帧,当我想这么做的时候,却发现了一个问题,当时美术拼图的时候,最开始设计的是,每一个界面自己用一张自己的大图,外加一张公共用到的大图(该大图包含,所有公用的资源)后来,为了方便,也是自己经验不够,美术就没按照这个规则了,一张ui工程,用了自己的,也用了不是公用的大图,这样就导致优化的时候,不好释放精灵帧资源,以后这些细节还是很需要注意才行。还有一个问题,就是只要是在代码里面会有动态的加载图片的资源(不是加载cocostudio文件一次性加载的 通俗的讲 就是非静态图片) 那么务必用小图,不用大图,如果用了大图,将导致该大图不能被删除。 所以,以后我自己开发项目的时候, 是不允许出现 代码里面加载图片用 cocostudio里面的大图的。 现在想想,如果遵守了这几个规则,那么在我们各个界面的onexit() 函数内,释放掉他自己对应的大图,和大图内对应的精灵帧,那么也能节约不少内存,这个是结合cocostudio texturePacker texturecach sPRiteFrameCach 一起来讲的,也是我自己总结的。 上面说的是从 代码层面优化内存,还有几十从资源本身也可以做一些优化,但是有一点一直没有搞懂,就是网络上说什么图片格式不要用rgba8888的,要用什么rgba4444啥的,只知道大的背景图因为一般无需透明度,可以直接用jpg格式,而jpg格式其实是rgb888格式的, 给我的感觉是每个像素只占24个字节,但是当打印缓存内的jpg格式的大图的时候,发现他的格式一样的是每个像素占了32位,这我就搞不懂了。 还有什么rgba4444啥的,不知道是不是美术直接设置成这个格式,还是不是需要程序内再一次设置,没搞懂。 在这一点上,引擎文档也没有任何的说明。先记录到这。。。 接上,上次说到图片资源像素格式的问题,今天又针对性的跟踪了一下代码。 如果是png类型的图片,无论美术导出的是什么格式, 引擎在初始化image的时候,都会转换成 i8 ai88 rgb888 rgba8888 四种类型中的一种,也就是说 即便导出的是rgba4444 实际上会给image设置为rgba8888的格式,接着在初始化texture的时候, 会有一个convertDataToFormat步骤,会把当前image的格式转换成引擎默认用的像素format g_defaultAlphaPixelFormat 而 g_defaultAlphaPixelFormat默认设置的是rgba8888格式,所以我测试用一张 rgba4444 的图片 结果内存每个像素也是占32位。但是当发现如果用的是pvr格式的图片,如果用的是rgba4444格式,观察在内存中每个像素就只占16位,这就对了,因为引擎不会把rgba4444的转换为系统默认的格式,转换的时候,只对以上四种格式。 说的不清楚,我自己总结一下,引擎默认用的格式是rgba8888 32位像素格式,如果不改变,那么所有的png图片 在内存中都将会是每个像素占32位,当然如果改变默认的像素格式,那么占的内存也会对应的改变,而pvr格式的图片,如果设置成了rgba4444 他在内存就是每个像素16,有内存上的变小。 感觉说的不是很清楚,但是应该算是彻底懂了。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表