// PoolManager.cpp
PoolManager* PoolManager::s_singleInstance = nullptr;
PoolManager* PoolManager::getInstance()
{
if
(s_singleInstance == nullptr)
{
s_singleInstance =
new
PoolManager();
s_singleInstance->_curReleasePool =
AutoreleasePool();
// 第二个池:将new出来的释放池再一次压入池管理器中
s_singleInstance->_releasePoolStack.push_back(s_singleInstance->_curReleasePool);
}
return
s_singleInstance;
}
PoolManager::destroyInstance()
delete s_singleInstance;
s_singleInstance = nullptr;
}
PoolManager::PoolManager()
{
}
PoolManager::~PoolManager()
{
while
(!_releasePoolStack.empty())
{
AutoreleasePool* pool = _releasePoolStack.back();
_releasePoolStack.pop_back();
delete pool;
}
}
AutoreleasePool* PoolManager::getCurrentPool()
const
{
_curReleasePool;
}
PoolManager::push(AutoreleasePool *pool)
{
_releasePoolStack.push_back(pool);
_curReleasePool = pool;
}
PoolManager::pop()
{
CC_ASSERT(_releasePoolStack.size() >=
1
);
_releasePoolStack.pop_back();
(_releasePoolStack.size() >
)
{
_curReleasePool = _releasePoolStack.back();
}
貌似PoolManager功能更加简单,就是管理释放池。
四、内存管理思路
1、autorelease
new一个对象的时候,调用其autorelease将对象交给自动释放池管理
?
5
Ref* Ref::autorelease()
{
PoolManager::getInstance()->getCurReleasePool()->addObject(
);
return
;
}
|
2、PoolManager::getInstance()
在获取单例对象时,如果不存在则会创建一个PoolManager对象,这时候会添加两个释放池
引擎自己会维持两个默认的释放池,如果我们没有手动创建释放池,则autorelease对象都添加到栈顶默认释放池。
其实我还没弄懂这里为什么要有两个默认的释放池,一个也可以的。
3、getCurReleasePool()获取的是当前释放池,addObject()将Ref对象加入当前释放池中。<喎?"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">void AutoreleasePool::addObject(Ref* object) { _managedObjectArray.push_back(object); }这样,每一个调用autorelease的Ref对象都会添加到_managedObjectArray中。
4、自动释放池的对象是怎么释放的?看AutoreleasePool:clear()函数
这里循环_managedObjectArray调用里面对象的release,调用1次release,引用计数就减1,当引用计数为0时就delete该对象。
你肯定很疑惑,在哪里会调用clear函数呢,~AutoreleasePool()会调用,但是那是在delete的时候释放的,我们看到Director类的主循环:
看到这里就明白了吧,每一次主循环都会调用clear来release自动释放池的对象,而每一帧会执行一次主循环,也就是每一帧都会清除一次。
五、手动创建释放池
我们已经知道,调用了autorelease()方法的对象将会在自动释放池池释放的时候被释放一次。虽然Cocos2d-x已经保证每一帧结束后释放一次释放池,但是如果在一帧之内生成了大量的autorelease对象,将会导致释放池性能下降。因此在生存autorelease对象密集的区域(通常是循环中)的前后,最后手动创建一个释放池。
?
7
{
AutoreleasePool pool1;
()
{
ref->autorelease();
}
此时,引擎维护三个释放池,我们知道每一帧结束时会执行当前释放池的clear(),所以上面的那些对象就会在第一帧结束时被释放,而那些放在引擎默认释放池的autorelease对象就会在下一帧被释放,错开了释放的时间,这样就不会降低释放池的性能。
看到上面的代码,你会感到疑惑:为什么只有创建释放池,而没有释放。还记得在AutoreleasePool.h中AutoreleasePool构造函数的注释吗:不要在堆上创建,而应该在栈上。我们知道,new出来对象必须手动delete才能释放,而在栈上的变量,当作用域消失就会释放,如上面的pool1,当执行到最后一个“}”时就会调用其析构函数,看看AutoreleasePool构造和析构函数做了些什么:
3、Cocos2d-x内存管理的一种实现 http://www.cocoachina.com/applenews/devnews/2013/0531/6315.html
4、深入理解Cocos2d-x内存管理 http://www.cocoachina.com/applenews/devnews/2013/0621/6455.html
本文转自:http://www.2cto.com/kf/201407/314375.html
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|
|