`
fireDragonpzy
  • 浏览: 462673 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

ocos2d-x基础知识(九)cocos2d-x场景切换时内存过高导致crash 解决方法

阅读更多
最近在做一个cocos2d-x的项目时,遇到一个问题,就是在pc上运行都是ok的,可是在ipad和andriod上面,在场景切换时时常会挂掉,用苹果自带的Instruments工具检测时,发现在场景正常运行时,内存大概保持在三四十兆,但是在场景切换时,一瞬间会达到七八十兆,遇到一些素材比较多或者层比较多的场景,则会达到一百多兆。大家知道在ipad1上面,内存最大是128M,那么这个程序如果在ipad1上面运行,肯定会经常挂掉。遇到问题,只能一步步分析,一步步找。

(1)先把所有场景的retain的东西检查一遍,看看在onExit的时候有没有release掉,这个检查完以后,还是会crash,所以这种情况不是根源。

(2)对于有好几个层的场景,在init的时候,先加载第一个层的,而不是把所有层的东西全部加载完,在切换层的时候再加载相对应的层,这种方法果然有效,当切换到这个场景的时候,内存果然减少了一半左右。但是对于只有一个层的场景来说,在切换时也是会挂,所以问题还没有找完全。

(3)我们知道,在每个场景里面会有一个init函数,一个onEnterTransitionDidFinish函数,一个Onexit函数,init实现一些初始化工作,onEnterTransitionDidFinish在init之后执行,Onexit在场景退出时回收init时分配的资源。在调试时发现一个很有趣的现象,那就是从场景一切换到场景二时,在切换的一瞬间会内存会非常高,但是过了一段时间后,内存会回到一个平稳的状态,譬如切换时内存会达到80M,切换过后内存会降到50M。分析原因,怀疑是上一个场景的内存还没有释放,然后这一个场景的内存已经分配,所以两个叠加在一起,就比较高了。所以我便在第一个场景的Onexit函数中加一个断点,在第二个场景的init和onEnterTransitionDidFinish函数中各加一个断点,然后运行程序,发现程序先到第二个场景的init中,然后再回到第一个场景的Onexit中,最后才到第二个场景的onEnterTransitionDidFinish中。我才恍然大悟,原来在场景切换时,不是马上会执行第一个场景的Onexit函数,而是先到第二个场景的init中加载资源,然后回到第一个场景中释放资源,最后才是到onEnterTransitionDidFinish中。

最终解决方法:

把一些资源的初始化放到onEnterTransitionDidFinish中进行,那么究竟应该把那些资源放到onEnterTransitionDidFinish中初始化,而那些资源又只能放到init中呢?

(1)像背景图这种只能放到init中,像场景切换时要看到的一些精灵,必须放到init中,不然场景切换时会看不到背景或者一些精灵。

(2)象精灵的一些动画,动作,可以放到onEnterTransitionDidFinish中来初始化。

举个例子:

譬如一只船在划动,那么船这只精灵在场景切换时要展示,所以必须放在init中

//小船精灵的加载

m_boatAction = CCSprite::spriteWithFile(s1_little_boat1);  
    addChild(m_boatAction);  
    m_boatAction->setPosition( CCPointMake(s.width/2, s.height/2+130));  
    m_boatAction->setScale(0.3);  
    m_boatAction->retain();  

 

而船划动的动作,就可以放到onEnterTransitionDidFinish来初始化和执行


CCSize s = CCDirector::sharedDirector()->getWinSize();  
    CCAnimation* animation = CCAnimation::animation();  
    char frameName[100] = {0};  
    for( int i=1;i<=5;i++)  
    {  
        sprintf(frameName, "scene1/little_boat%d.png", i);  
        animation->addFrameWithFileName(frameName);  
    }  
  
    CCActionInterval*  action = CCAnimate::actionWithDuration(2, animation, false);  
    repeatAction = CCRepeatForever::actionWithAction(action);  
    repeatAction->retain();  
通过这三步,基本上就可以避免在场景切换时内存过而导致crash的情况

缓存释放
如果游戏有很多场景,在切换场景的时候可以把前一个场景的内存全部释放,防止总内存过高.
CCTextureCache::sharedTextureCache()->removeAllTextures(); 释放到目前为止所有加载的图片
CCTextureCache::sharedTextureCache()->removeUnusedTextures(); 将引用计数为1的图片释放掉CCTextureCache::sharedTextureCache()->removeTexture(); 单独释放某个图片
CCSpriteFrameCache 与 CCTextureCache 释放的方法差不多。

场景的切换:
值得注意的是释放的时机,一般在切换场景的时候释放资源,如果从A场景切换到B场景,调用的函数顺序为
            1、如果没有切换效果,则为B的init(),A的onExit(),B的onEnter()
            2、如果有切换效果,则为B的init(),B的onEnter(),A的onExit()
有时强制释放全部资源时,会使某个正在执行的动画失去引用而弹出异常,可以调用CCActionManager::sharedManager()->removeAllActions();来解决。


摘自:http://blog.csdn.net/zhangjingyangguang/article/details/7618048
分享到:
评论

相关推荐

    ocos2d-x默认项目注释Box2D

    在 cocos2d-x 中集成Box2D时,我们需要引入Box2D的头文件,例如`#include "Box2D/Box2D.h"`。然后,我们可以创建World对象,设置重力环境,如`b2Vec2 gravity(0.0f, -10.0f);`和`world = new b2World(gravity);`。...

    ocos2d-x 通过JNI实现c/c++和Android的java层函数互调

    cocos2d-x 通过JNI实现c/c++和Android的java层函数互调, 本文主要实现两个功能: (1)通过Android sdk的API得到应用程序的包名(PackageName),然后传递给c++层函数。 (2)通过c++函数调用Android的java层函数,显示一...

    cocos2d-X字体编辑器

    为了以ocos2d可用的格式保存字体,需要通过File | Export以.fnt(cocos2d Text)格式保存它。然后可以在Xcode项目中添加使用Glyph Designer创建的FNT和PNG文件,并在CCLabelBMFont类中使用FNT文件。

    像素小鸟(flappy bird) cocos creator 完整源码

    《像素小鸟(Flappy Bird):Cocos Creator 2.4.2完整源码解析》 像素小鸟(Flappy Bird)是一款曾经风靡全球的休闲小游戏,以其简单却极具挑战性的玩法吸引了无数玩家。本资源提供了使用Cocos Creator 2.4.2版本制作的...

    BeautyShow

    6. **优化和调试**:在实现过程中,我们需要关注性能优化,比如避免一次性加载所有图片导致内存占用过高,可以使用延迟加载或动态加载策略。同时,调试工具如`log`输出和断点调试,可以帮助我们找出并修复潜在的问题...

    ocos2源码

    《ocos2源码详解与应用实例》 ocos2,全称是OpenRTOS,是一个轻量级的操作系统内核,主要用于嵌入式系统。它提供了一种高效、可靠且可扩展的实时操作系统解决方案,广泛应用于物联网、工业自动化、汽车电子、消费...

    高中三角函数公式大全.pdf

    * 图象的解析式:y=Asin( ω x+φ )、y=Acos( ω x+φ )、y=Atan( ω x+φ ) 本资源摘要信息对高中三角函数公式大全进行了详细的知识点总结,涵盖了角的表示方法、弧度制与三角函数、任意角的三角函数、三角函数...

    FlappyBird:cocos2dx3.3 c++版 只在iphone上测试过

    cocos2dx3.3 c++版 只在iphone上测试过 本人QQ:632840804 本人Email: 写代码不易,写教程亦不易,且写且看且珍惜!!! 写代码不易,写教程亦不易,且写且看且珍惜!!! 写代码不易,写教程亦不易,且写且看且珍惜...

    casio 5800 直线程序(正,反算)

    7. 使用公式 `N+(S-K)Cos(F)+OCos(F+90)→X` 计算新的X坐标,其中N为起点的X坐标。 8. 使用公式 `E+(S-K)Sin(F)+OSin(F+90)→Y` 计算新的Y坐标,其中E为起点的Y坐标。 9. 显示新坐标X和Y,并返回主菜单,等待下一次...

    桂林理工大学计算机专业嵌入式stm32大作业

    在这个项目中,学生们将接触到多个关键知识点,包括Ocos操作系统、矩阵键盘的操作以及ADC模数转换。 1. **Ocos操作系统**: Ocos(Open Control Operating System)是一个开源的实时操作系统,适用于嵌入式系统。...

    三相三线制电度表的接线方式和计算.doc

    三相三线制电度表的接线方式和计算是电力系统中一个重要的知识点。三相电能表的接线方式直接影响电能表的计量结果,正确的接线方式可以确保电能表的准确计量,而错误的接线方式会导致电能表的计量错误甚至反转。 ...

    2022年高二数学学业水平模拟考试题宣贯.pdf

    1. 集合的基本运算:题目中提到了集合的交集运算,例如集合A和B的交集BAC R),这涉及到集合论的基础知识,包括集合的定义、元素关系以及集合的运算规则。 2. 函数的定义域:函数)4(log3 xy的定义域为(),这需要...

    OCRAW

    fengsiranIO个人主要分销仓库这是一个用作分发文件的仓库,如果您要寻找文件,最好的方法是前往我们的,或者在该库中查找资源。关于我们的GitHub,Coding GitHub的fengsiran名下的存储库用于Git访问,拉请求和大资源...

    微波技术及天线实验2利用HFSS仿真分析矩形波导.doc

    Ez = E0ocos(kz + Φ) 其中,Ez是电场强度,E0是电场振幅,k是波数,z是位置坐标,Φ是相位角。 TM模式的计算公式为: Hz = H0ocos(kz + Φ) 其中,Hz是磁场强度,H0是磁场振幅,k是波数,z是位置坐标,Φ是相位...

    最全的oracle常用命令大全.txt

    下面按类别列出一些ORACLE用户常用数据字典的查询使用方法。 1、用户 查看当前用户的缺省表空间 SQL&gt;select username,default_tablespace from user_users; 查看当前用户的角色 SQL&gt;select * from user_...

Global site tag (gtag.js) - Google Analytics