您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x内存管理机制剖析

2013-03-17 18:14 351 查看
cocos2d-x的内存管理机制是基于一种引用计数的思想,类中有一个变量保存引用该对象的模块个数,对象被从堆上创建时,引用计数默认为1; 如果有模块需要引用该对象,将它引用计数加1;不需要引用时,将引用计数减1,引用计数为0时释放该对象。

cocos2d-x引用计数功能集成在CCObject类,核心源码如下:

头文件:

class CCObject
{
protected:
// 引用计数
unsigned int        m_uReference;
// 是否自动释放
bool        m_bManaged;
};


源文件:

/*
* 不需引用对象时调用
*/
void CCObject::release(void)
{
CCAssert(m_uReference > 0, "reference count should greater than 0");
--m_uReference;

if (m_uReference == 0)
{
delete this;
}
}

/*
* 引用对象时调用
*/
void CCObject::retain(void)
{
CCAssert(m_uReference > 0, "reference count should greater than 0");
++m_uReference;
}
/*
* 自动释放,加入内存释放池
*/
CCObject* CCObject::autorelease(void)
{
CCPoolManager::sharedPoolManager()->addObject(this);

m_bManaged = true;
return this;
}


类需要使用引用计数功能时继承CCObject类,从堆上创建对象,引用默认为1,如果不想显式释放对象,可以将对象加入到内存释放池,cocos2d-x内存管理模块会在每一帧调用内存释放池释放加入到池中的对象。

cocos2d-x内存管理模块核心源如下:

头文件:

/**
* @addtogroup base_nodes
*             默认释放池
*/
class CC_DLL CCAutoreleasePool : public CCObject
{
CCArray*    m_pManagedObjectArray;
public:
CCAutoreleasePool(void);
~CCAutoreleasePool(void);

void addObject(CCObject *pObject);
void removeObject(CCObject *pObject);

/*释放池中所有对象*/
void clear();
};

/*
* 释放池管理模块
*/
class CC_DLL CCPoolManager
{
/*程序结束时调用,释放所有池中的对象*/
void finalize();

/*增加内存池,在主程序启动时调用*/
void push();

/*每一帧、程序退出时调用, 释放内存池对象,当内存池个数大于1时,同时释放内存池*/
void pop();

/*从内存池中删除对象*/
void removeObject(CCObject* pObject);

/*把对象加入到内存池中*/
void addObject(CCObject* pObject);

static CCPoolManager* sharedPoolManager();

/*程序退出时调用*/
static void purgePoolManager();

};


CCDirector.cpp代码片段:

bool CCDirector::init(void)
{
...
// create autorelease pool
CCPoolManager::sharedPoolManager()->push();
...
}
CCDirector::~CCDirector(void)
{
...
// pop the autorelease pool
CCPoolManager::sharedPoolManager()->pop();
CCPoolManager::purgePoolManager();
...
}


为了省略不相关的代码使用[...]符号

CCDisplayLinkDirector.cpp代码片段:

void CCDisplayLinkDirector::mainLoop(void)
{
if (m_bPurgeDirecotorInNextLoop)
{
m_bPurgeDirecotorInNextLoop = false;
purgeDirector();
}
else if (! m_bInvalid)
{
drawScene();

// release the objects
CCPoolManager::sharedPoolManager()->pop();
}
}

mainLoop函数在每帧时调用,函数再调用 CCPoolManager::sharedPoolManager()->pop(); 释放当前池的所有对象 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: