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

 

 

posted @ 2016-12-13 19:27  LT.C#  阅读(165)  评论(0编辑  收藏  举报