【转】cocos2d-x与ios内存管理分析(在游戏中减少内存压力)
猴子原创,欢迎转载。转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢!
注:自己以前也写过cocos2d-x如何优化内存的使用,以及内存不足的情况下怎么处理游戏。今天在微博中看到有朋友介绍了下内存,挺详细的。不知道是谁写的,我记录下。
一,IOS与图片内存
在IOS上,图片会被自动缩放到2的N次方大小。比如一张1024*1025的图片,占用的内存与一张1024*2048的图片是一致的。图片占用 内存大小的计算的公式是;长*宽*4。这样一张512*512 占用的内存就是 512*512*4 = 1M。其他尺寸以此类推。(ps:IOS上支持的最大尺寸为2048*2048)。
二,cocos2d-x 的图片缓存
Cocos2d-x 在构造一个精灵的时候会使用spriteWithFile或者spriteWithSpriteFrameName等 无论用哪种方式,cocos2d-x都会将这张图片加载到缓存中。如果是第一次加载这个图片,那就会先将这张图片加载到缓存,然后从缓存读取。如果缓存中 已经存在,则直接从缓存中提取,免除了加载过程。
图片的缓存主要由以下两个类来处理:CCSpriteFrameCache, CCTextureCache
CCSpriteFrameCache加载的是一张拼接过的大图,每一个小图只是大图中的一个区域,这些区域信息都在plist文件中保存。用的时候只需要根据小图的名称就可以加载到这个区域。
CCTextureCache 是普通的图片缓存,我们所有直接加载的图片都会默认放到这个缓存中,以提高调用效率。
因此,每次加载一张图片,或者通过plist加载一张拼接图时,都会将整张图片加载到内存中。如果不去释放,那就会一直占用着。
三,渲染内存。
不要以为,计算内存时,只计算加载到缓存中的内存就可以了。以一张1024*1024的图片为例。
CCSprite *pSprite = CCSprite::spriteWithFile(“a.png”);
调用上边这行代码以后,可以在LEAKS工具中看到,增加了大约4M的内存。然后接着调用
addChild(pSprite);
这时,内存又增加了4M。也就是,一张图片,如果需要渲染的话,那它所占用的内存将要X2。
再看看通过plist加载的图片,比如这张大图尺寸为2048*2048。想要加载其中的一张32*32的小图片
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(“b.plist”);
此时内存增加16M (汗)
CCSprite *pSpriteFrame = CCSprite::spriteWithSpriteFrameName(“b1.png”);
b.png 大小为32*32 ,想着也就是增加一点点内存,可实际情况是增加16M内存。也就是只要渲染了其中的一部分,那么整张图片都要一起被加载。
但是情况不是那么的糟糕,这些已经渲染的图片,如果再次加载的话,内存是不会再继续升高的,比如又增加了100个b.plist的另一个区域,图片内存还是共增加16+16 = 32M,而不会继续上升。
四,缓存释放
如果游戏有很多场景,在切换场景的时候可以把前一个场景的内存全部释放,防止总内存过高.
CCTextureCache::sharedTextureCache()->removeAllTextures(); 释放到目前为止所有加载的图片
CCTextureCache::sharedTextureCache()->removeUnusedTextures();
将引用计数为1的图片释放掉CCTextureCache::sharedTextureCache()->removeTexture();
单独释放某个图片
CCSpriteFrameCache 与 CCTextureCache 释放的方法差不多。
值得注意的是释放的时机,一般在切换场景的时候释放资源,如果从A场景切换到B场景,调用的函数顺序为B::init()—->A::exit()—->B::onEnter() 。
可如果使用了切换效果,比如CTransitionJumpZoom::transitionWithDuration这样的函数,则函数的调用顺序变为B::init()—->B::onEnter()—->A::exit() 。
而且第二种方式会有一瞬间将两个场景的资源叠加在一起,如果不采取过度,很可能会因为内存吃紧而崩溃。
有时强制释放全部资源时,会使某个正在执行的动画失去引用而弹出异常,可以调用CCActionManager::sharedManager()->removeAllActions();来解决。
五,内存优化
优化的心得就是尽量去拼接图片,使图片边长尽可能的保持2的N次方并且装的很满。但要注意,有逻辑关系的图片尽量打包在一张大图里,另外一点就是打
包的时候要考虑到层的分布。因为为了渲染效率可能会用到CCSpriteBatchNode;同一个BatchNode里的图片都是位于一个层级的,因此
必须根据各个图片的层级关系,打包到不同的plist里。有时内存和效率不可以兼得,只能尽量平衡了。
六,其他
最后附一个各代IOS设备的内存限制情况
设备 建议内存 最大内存
iPad2/iPhone4s/iphone4 170-180mb 512mb
iPad/iPod touch3,4/iphone3gs 40-80mb 256mb
iPod touch1,2/iPhone3g/iPhone1 25mb 128mb
上述建议内存只是一些人自己测试的结果,可用的RAM不大于最大内存的一半,如果程序超过最大内存的一半,则可能会挂掉。
另外在LEAKS里查看模拟器中和真机总的内存,会有较大出入。在模拟器中的结果与实际更接近一些。
- 本文固定链接: http://www.cocos2dev.com/?p=281
- 转载请注明: Houzi 2012年07月24日 于 Cocos2D开发网 发表
【转】cocos2d-x与ios内存管理分析(在游戏中减少内存压力)的更多相关文章
- cocos2d-x与ios内存管理分析(在游戏中减少内存压力)
转自:http://www.cocos2dev.com/?p=281 注:自己以前也写过cocos2d-x如何优化内存的使用,以及内存不足的情况下怎么处理游戏.今天在微博中看到有朋友介绍了下内存,挺详 ...
- java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
- arm-linux内存管理学习笔记(1)-内存页表的硬件原理
linux kernel集中了世界顶尖程序猿们的编程智慧,犹记操作系统课上老师讲操作系统的四大功能:进程调度 内存管理 设备驱动 网络.从事嵌入式软件开发工作,对设备驱动和网络接触的比較多. 而进程调 ...
- C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针
C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针 (1)开辟的内存没有释放,造成内存泄露 (2)野指针被使用或释放 (3)非法释放指针 (1)开辟的内存没有释放.造成内存泄露,以下的样 ...
- JavaScript如何工作:内存管理+如何处理4个常见的内存泄漏
摘要: 作者将自己常用的JavaScript模块分享给大家. 原文:JavaScript如何工作:内存管理+如何处理4个常见的内存泄漏 作者:前端小智 Fundebug经授权转载,版权归原作者所有. ...
- 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组
学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...
- iOS 内存管理分析
内存分析 静态分析(Analyze) 不运行程序, 直接检测代码中是否有潜在的内存问题(不一定百分百准确, 仅仅是提供建议) 结合实际情况来分析, 是否真的有内存问题 动态分析(Profile == ...
- Android 内存管理分析(四)
尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8920039 最近在网上看了不少Android内存管理方面的博文,但是文章大多 ...
- memcached 内存管理 分析(转)
Memcached是一个高效的分布式内存cache,了解memcached的内存管理机制,便于我们理解memcached,让我们可以针对我们数据特点进行调优,让其更好的为我所用.这里简单谈一下我对me ...
随机推荐
- PHP ServerPush
原文:http://yorsal.com/archives/302 随着人们对Web即时应用需求的不断上升,Server Push(推送)技术在聊天.消息提醒尤其是社交网络等方面开始兴起,成为实时应用 ...
- OneAlert:国内首家 SaaS 模式的云告警平台
随着互联网行业的高速发展,企业 IT 应用环境日趋复杂.几分钟的故障就会严重到用户体验,那么如何有效降低IT故障带来的影响呢?权威数据表明,86%的企业认为建立有效的监控系统和告警系统.提升 IT 的 ...
- [Ruby on Rails系列]6、一个简单的暗语生成器与解释器(上)
[0]Ruby on Rails 系列回顾 [Ruby on Rails系列]1.开发环境准备:Vmware和Linux的安装 [Ruby on Rails系列]2.开发环境准备:Ruby on Ra ...
- Xamarin.Android 入门之:Xamarin快速入门
一. 准备工作 1.新建一个项目取名为phoneword 2.在项目创建好之后,让我们展开“Resources”文件夹然后找到并打开该文件夹下的“layout”文件夹,双击main.axml在Andr ...
- C# 常用对象的的修饰符
class(类) 1.internal 表示类只能在当然程序集中访问,类默认修饰符 2.public 表示所有地方都可以访问,与internal是互斥的 3.abstract 抽象类,不能被实例化,只 ...
- JBoss - 调整JVM内存 -Xms512m -Xmx1024m
$JBOSS-HOME/server/下有3个目录,all/default/minimal,它们是表示3种配置,全部的配置.默认配置.最小配置,我们在启动JBOSS服务时,可以指定 run –c al ...
- Ios tab Bar 使用方法
http://blog.sina.com.cn/s/blog_63578f140100w56m.html UITabBar* tabBar = [[UITabBar alloc] initWithFr ...
- apk反编译(4)Smali代码注入
转自 : http://blog.sina.com.cn/s/blog_5674d18801019i89.html 应用场景 Smali代码注入只能应对函数级别的移植,对于类级别的移植是无能为力的.具 ...
- ie6调试工具Debugbar
http://www.my-debugbar.com/wiki/Doc/DebugbarInstall
- js 中 typeof 的使用
js中的变量是松散类型(即弱类型)的,可以用来保存任何类型的数据. typeof 可以用来检测给定变量的数据类型,可能的返回值: 'undefined' --- 这个值未定义 'boolean' -- ...