cocos 自动内存管理分析
#include "CCAutoreleasePool.h" #include "ccMacros.h" NS_CC_BEGIN static CCPoolManager* s_pPoolManager = NULL; CCAutoreleasePool::CCAutoreleasePool(void) { m_pManagedObjectArray = new CCArray(); m_pManagedObjectArray->init(); } CCAutoreleasePool::~CCAutoreleasePool(void) { CC_SAFE_DELETE(m_pManagedObjectArray); } void CCAutoreleasePool::addObject(CCObject* pObject)//添加对象,再释放一次,对象的引用为1 { m_pManagedObjectArray->addObject(pObject);//1+1 CCAssert(pObject->m_uReference > 1, "reference count should be greater than 1"); ++(pObject->m_uAutoReleaseCount); pObject->release(); // -1 } void CCAutoreleasePool::removeObject(CCObject* pObject) { for (unsigned int i = 0; i < pObject->m_uAutoReleaseCount; ++i) { m_pManagedObjectArray->removeObject(pObject, false); } } void CCAutoreleasePool::clear()//清理上帧自动管理的对象(每个obj的引用-1) { if(m_pManagedObjectArray->count() > 0) { //CCAutoreleasePool* pReleasePool; #ifdef _DEBUG int nIndex = m_pManagedObjectArray->count() - 1; #endif CCObject* pObj = NULL; CCARRAY_FOREACH_REVERSE(m_pManagedObjectArray, pObj) { if(!pObj) break; --(pObj->m_uAutoReleaseCount); //(*it)->release(); //delete (*it); #ifdef _DEBUG nIndex--; #endif } m_pManagedObjectArray->removeAllObjects(); } } //-------------------------------------------------------------------- // // CCPoolManager // //-------------------------------------------------------------------- CCPoolManager* CCPoolManager::sharedPoolManager() { if (s_pPoolManager == NULL) { s_pPoolManager = new CCPoolManager(); } return s_pPoolManager; } void CCPoolManager::purgePoolManager() { CC_SAFE_DELETE(s_pPoolManager); } CCPoolManager::CCPoolManager()//m_pReleasePoolStack 用于储存 CCAutoreleasePool { m_pReleasePoolStack = new CCArray(); m_pReleasePoolStack->init(); m_pCurReleasePool = 0; } CCPoolManager::~CCPoolManager() { finalize(); // we only release the last autorelease pool here m_pCurReleasePool = 0; m_pReleasePoolStack->removeObjectAtIndex(0); CC_SAFE_DELETE(m_pReleasePoolStack); } void CCPoolManager::finalize() { if(m_pReleasePoolStack->count() > 0) { //CCAutoreleasePool* pReleasePool; CCObject* pObj = NULL; CCARRAY_FOREACH(m_pReleasePoolStack, pObj) { if(!pObj) break; CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj; pPool->clear(); } } } void CCPoolManager::push()//创建一个 m_pCurReleasePool 添加到 m_pReleasePoolStack { CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1 m_pCurReleasePool = pPool; m_pReleasePoolStack->addObject(pPool); //ref = 2 pPool->release(); //ref = 1 } void CCPoolManager::pop()//每帧执行一次,如果 m_pReleasePoolStack 有则开始清理。 { if (! m_pCurReleasePool) { return; } int nCount = m_pReleasePoolStack->count(); m_pCurReleasePool->clear(); if(nCount > 1) { m_pReleasePoolStack->removeObjectAtIndex(nCount-1); // if(nCount > 1) // { // m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2); // return; // } m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2); } /*m_pCurReleasePool = NULL;*/ } void CCPoolManager::removeObject(CCObject* pObject) { CCAssert(m_pCurReleasePool, "current auto release pool should not be null"); m_pCurReleasePool->removeObject(pObject); } void CCPoolManager::addObject(CCObject* pObject) { getCurReleasePool()->addObject(pObject); } CCAutoreleasePool* CCPoolManager::getCurReleasePool()//获取本帧的 m_pCurReleasePool ,每帧的m_pCurReleasePool都是新的(因为被清了) { if(!m_pCurReleasePool) { push(); } CCAssert(m_pCurReleasePool, "current auto release pool should not be null"); return m_pCurReleasePool; } NS_CC_END
大致思路就是:有CCPoolManager 与CCAutoreleasePool
程序是按帧,一帧一帧运行的
每帧执行的程序创建的obj如果使用了autorelease(CCObject的)会将obj添加到CCAutoreleasePool,这个在本帧惟一的,CCAutoreleasePool会被添加到CCPoolManager
每次mainLoop会执行内存清理(CCPoolManager的pop) 对上一帧保存的对象release 。也可以说是CCPoolManager 删除上次的CCAutoreleasePool。 如果上一帧的对象引用为1(初始为1)就会被释放掉。大于1不会被释放,但也不会再管了。
如果obj被添加到CCAutoreleasePool obj的m_uAutoReleaseCount会+1,直到从CCAutoreleasePool删除时-1.