cocos2d-x源码中的内存管理
来源:互联网 发布:穆斯林 知乎 编辑:程序博客网 时间:2024/06/15 22:47
cocos2d-x的内存管理原则——引用计数机制
内存管理:引用计数机制, 当一个对象执行retain操作的时候,引用计数加1,当执行release操作的时候,引用计数减1,当引用计数为0时,此对象被释放。
通过基类Ref的代码实现,便可以明白基本的内存管理机制,直接打开 CCRef.cpp
文件
// 我们直接来看看CCRef.cpp文件Ref::Ref(): _referenceCount(1) //注:当Ref对象被创建,此对象的引用计数为1void Ref::retain() //retain方法{ CCASSERT(_referenceCount > 0, "reference count should be greater than 0"); ++_referenceCount; //引用计数加1}void Ref::release() //release方法{ CCASSERT(_referenceCount > 0, "reference count should be greater than 0"); --_referenceCount; //引用计数减1 if (_referenceCount == 0) //当引用计数为0的时候,删除对象 {#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) auto poolManager = PoolManager::getInstance(); if (!poolManager->getCurrentPool()->isClearing() && poolManager->isObjectInPools(this)) { CCASSERT(false, "The reference shouldn't be 0 because it is still in autorelease pool."); }#endif delete this; //删除对象!!! }}Ref* Ref::autorelease() //autorelease方法{ PoolManager::getInstance()->getCurrentPool()->addObject(this); //将对象加入到自动释放池中 return this;}unsigned int Ref::getReferenceCount() const{ return _referenceCount; //获取引用计数个数}
通过看Ref类的源码,可以得出结论:
1.当一个对象被创建的时候,将此对象的引用计数设置为12.当执行一次retain,引用计数加1,3.执行一次release,引用计数减14.当引用计数为0的时候,此对象被释放delete
Ref的autorelease方法
Ref* Ref::autorelease() //autorelease方法{ PoolManager::getInstance()->getCurrentPool()->addObject(this); //将对象加入到自动释放池中 return this;}
什么时候调用autorelease方法?
Label* Label::create() { auto ret = new (std::nothrow) Label; if (ret) { ret->autorelease(); //create函数里,会自动执行autorelease方法 } return ret; }
可以看出,在create函数里,会自动执行autorelease方法, 也就是加入到自动释放池
AutoreleasePool
自动释放池:
它有个属性_managedObjectArray,可以将执行了autorelease方法的Ref对象加入_managedObjectArray,当AutoreleasePool::clear()时,也就是对_managedObjectArray中的每一项执行release操作
PoolManager
自动释放池管理类
有个生成器属性_releasePoolStack,里面加入的都是AutoreleasePool的对象,可以获取当前的AutoreleasePool
可以看到实现是建立了一个PoolManager的单例,接下来看看PoolManager,有个生成器属性_releasePoolStack
PoolManager* PoolManager::s_singleInstance = nullptr;PoolManager* PoolManager::getInstance(){ //PoolManager是个单例 if (s_singleInstance == nullptr) { s_singleInstance = new (std::nothrow) PoolManager(); // Add the first auto release pool new AutoreleasePool("cocos2d autorelease pool"); } return s_singleInstance;}AutoreleasePool* PoolManager::getCurrentPool() const{ return _releasePoolStack.back(); //_releasePoolStack最后的一个AutoreleasePool对象}//注意接下来的两个函数:push,popvoid PoolManager::push(AutoreleasePool *pool){ _releasePoolStack.push_back(pool); //在_releasePoolStack这个vector尾部加入pool}void PoolManager::pop(){ CC_ASSERT(!_releasePoolStack.empty()); _releasePoolStack.pop_back();//删除_releasePoolStack最后一个元素}
PoolManager::getInstance()->getCurrentPool()->addObject(this)中的getCurrentPool可以看出获取到了一个AutoreleasePool对象,然后我们查看AutoreleasePool
class CC_DLL AutoreleasePool{ private: std::vector<Ref*> _managedObjectArray; //AutoreleasePool有个生成器属性_managedObjectArray,用来装Ref对象};void AutoreleasePool::addObject(Ref* object){ _managedObjectArray.push_back(object);}void AutoreleasePool::clear() //清楚操作{#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) _isClearing = true;#endif std::vector<Ref*> releasings; releasings.swap(_managedObjectArray); //遍历_managedObjectArray,为每一个对象执行release操作 for (const auto &obj : releasings) { obj->release(); }#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) _isClearing = false;#endif}
PoolManager::getInstance()->getCurrentPool()->addObject(this)中的addObject其实就是给_managedObjectArray这个vector中添加一个Ref对象
可以看到AutoreleasePool::clear()的方法实现,其实是把_managedObjectArray里面的每一个对象执行一次release操作,clear函数会在DisplayLinkDirector
的mainLoop函数中被调用,一帧调用一次,及时回收。
void DisplayLinkDirector::mainLoop(){ if (_purgeDirectorInNextLoop) { _purgeDirectorInNextLoop = false; purgeDirector(); } else if (_restartDirectorInNextLoop) { _restartDirectorInNextLoop = false; restartDirector(); } else if (! _invalid) { drawScene(); // release the objects !!!在此处执行clear操作 PoolManager::getInstance()->getCurrentPool()->clear(); }}
总结一下就是内存管理的源代码实现:
常见的label,button等对象在执行create()函数的时候,会自动执行autorelease()方法,就是将对象添加到AutoreleasePool的_managedObjectArray中,而在游戏中每一帧都会调用通过PoolManager获取到当前的AutoreleasePool对象,然后执行AutoreleasePool::clear()方法,给_managedObjectArray中的每一个对象执行release操作。
- cocos2d-x源码中的内存管理
- 【Cocos2d-x源码分析】 Cocos2d-x内存管理解析
- 【cocos2d-x游戏开发】Cocos2d-x中的内存管理
- 解析Cocos2d-x中的Ref内存管理
- Cocos2d-x 内存管理
- cocos2d-x:内存管理
- Cocos2d-x内存管理
- Cocos2d-x内存管理
- COCOS2D-X内存管理
- Cocos2d-x 内存管理
- cocos2d-x内存管理
- cocos2d-x内存管理
- cocos2d-x 内存管理
- Cocos2d-x 内存管理
- Cocos2d-x内存管理
- cocos2d-x 内存管理
- Cocos2d-x内存管理
- Cocos2d-x::内存管理
- java集合list的三个子类
- 教你在windows安装linux虚拟机
- python 标准输出 sys.stdout 重定向
- SSM整合开发的小Demo----毕业设计管理系统之管理员模块
- 递归与尾递归
- cocos2d-x源码中的内存管理
- BeagleBone Black (ubuntu)(u-boot)使用串口
- 反射
- Android 卡片翻转动画效果
- Clion 问题汇总
- C---动态内存分配
- 最优服务次序问题(贪心算法)
- CENTOS7搭建FTP服务器的具体步骤
- ES6