zoukankan      html  css  js  c++  java
  • cocos2d-x内存管理

    Cocos2d-x内存管理

     

     

     

     

     

           老师让我给班上同学讲讲cocos2d-x的内存管理,时间也不多,于是看了看源码,写了个提纲和大概思想

    一.   为什么需要内存管理

    1. new和delete

    2. 堆上申请的内存作用于整个程序,而不是一个两个函数之内

    3. 渲染树和整个游戏循环->引导出内存管理(全局变量,局部变量,和堆上申请的变量比较)

    注:游戏循环:可以看作一种死循环

    1. 绘制
    2. 自动释放池的计数管理

    绘制:包括时间调度,绘制结点等等

    if (_purgeDirectorInNextLoop)

        {

            _purgeDirectorInNextLoop = false;

            purgeDirector();

        }

        else if (_restartDirectorInNextLoop)

        {

            _restartDirectorInNextLoop = false;

            restartDirector();

        }

        else if (! _invalid)

        {

            drawScene();

        

            // release the objects

            PoolManager::getInstance()->getCurrentPool()->clear();

        }

    由上面的内容可以得出:

    1.内存管理并不仅仅局限于游戏开发,基本上只要是C++,C

    开发出来的大中型项目都必须要有内存管理。

           2.内存管理不只有引用计数一种,还有垃圾回收机制

    二.   Cocos2d-x内存管理机制

    一.   用法:

    第一种:retain,release

    第二种:autorelease(重点)

    Ref类,AutoReleasePool类,PoolManager类

    Ref类

    成员

    unsigned int _refCount;

    主要函数

                  void retain();

            void release();

    CCRef* autorelease();

    AutoReleasePool类

    成员

    std::vector<CCRef*> _managedObjectArray;

    std::string _name;

    主要函数

            AutoReleasePool();

            AutoReleasePool(const std::string &name);

     

            void addObject(CCRef* object);

            void clear();

     

            ~AutoReleasePool();

    PoolManager类

    成员

    std::vector<AutoReleasePool *> _releasePoolStack;

            static PoolManager* s_singleInstance;

    主要函数

    PoolManager();

    static PoolManager* getInstance();

    AutoReleasePool *getCurrentPool() const;

    void push(AutoReleasePool* pool);

    void pop();

    以上的三个类内存管理的描述:

    AutoRelease类的主要成员其实是一个队列,这个队列存放着当前帧的所有元素,

    而Poolmanager类其实是一个栈,这个栈存放着所有的AutoRelease,

    我们可以通过一次次的遍历这些队列,对ref中的引用计数值递减,当他们递减到0时,就可以自动删除了

    看看这个代码:

    Sprite->autorelease();

    他的实现是:

    PoolManager::getInstance()->getCurrentPool()->addObject(this);

    return this;

                       也就是说,每次自动内存管理就是把sprite加到最上面的那个队列中,

                       到这里,我们要问一下,一直都没有减少引用计数,怎么减少呢?

    控制引用计数的函数是:

    AutoRealease::Clear();

    什么时候调用呢?

    PoolManager::getInstance()->getCurrentPool()->clear();

    这个函数在Director::MainLoop()里面

    每一次帧循环都会调用一次这个函数,实现了自动内存管理

    练习:手动创建释放池

    我们已经知道,调用了autorelease()方法的对象将会在自动释放池池释放的时候被释放一次。虽然Cocos2d-x已经保证每一帧结束后释放一次释放池,但是如果在一帧之内生成了大量的autorelease对象,将会导致释放池性能下降。因此在生存autorelease对象密集的区域(通常是循环中)的前后,最后手动创建一个释放池。

      AutoreleasePool pool1;  // 手动创建一个释放池       

        for ()

        {  

            ref->autorelease();  // 循环里面执行autorelease,这些对象会添加到pool1中

        }

    }

     

     

     

        三.CreateFunc(宏)

     

     

    其他:cocos2d-x内存管理机制简洁重现:github链接:https://github.com/JKGameEngine/cocos2d-

     

    游戏循环的理解:参考博客

    http://blog.csdn.net/elloop/article/details/50290423

     

     

    内存管理博客推荐:

    http://www.2cto.com/kf/201407/314375.html

    http://www.cnblogs.com/mmidd/p/3746256.html

     

  • 相关阅读:
    python IDLE 如何实现清屏
    协同过滤算法(天池竞赛试题)
    二次排序
    异常类面试题
    异常类
    2020年Java程序员应该学习的10大技术
    java-servlet-EL表达式和java标签
    java-servlet过滤器和监听
    java-Servlet-cookie and session
    java-servlet-转发AND路径
  • 原文地址:https://www.cnblogs.com/YTYMblog/p/6171185.html
Copyright © 2011-2022 走看看