浅谈自己对cocos2dx的内存管理的理解

拿个自己写Layer的例子

1         auto genMenuWnd = GeneralMenuWnd::create();
2         CC_BREAK_IF(!genMenuWnd);
3         addChild(genMenuWnd, 100);

该引用计数变化流程

GeneralMenuWnd在create()的时候,其_referenceCount 为1,并在create()的时候autorelease();

addChild()的时候,其_referenceCount变为2;

当该帧执行完后,_referenceCount变为1;

genMenuWnd析构时,_referenceCount变为0, 删除;

大体是这样子的:

GeneralMenuWnd继承Ref,Ref的构造函数:

 1 Ref::Ref()
 2 : _referenceCount(1) // when the Ref is created, the reference count of it is 1 其引用计数默认为1
 3 #if CC_ENABLE_SCRIPT_BINDING
 4 , _luaID (0)
 5 , _scriptObject(nullptr)
 6 , _rooted(false)
 7 , _scriptOwned(false)
 8 ,_referenceCountAtRootTime(0)
 9 #endif
10 {
11 #if CC_ENABLE_SCRIPT_BINDING
12     static unsigned int uObjectCount = 0;
13     _ID = ++uObjectCount;
14 #endif
15
16 #if CC_REF_LEAK_DETECTION
17     trackRef(this);
18 #endif
19 }

在GeneralMenuWnd::create()中会调用autorelease(); 此时genMenuWnd会被放在AutoreleasePool里面.

1 Ref* Ref::autorelease()
2 {
3     PoolManager::getInstance()->getCurrentPool()->addObject(this);
4     return this;
5 }

执行addChild(), 流程addChild() --->  addChildHelper() ---> insertChild()

 1 void Node::addChild(Node* child, int localZOrder, const std::string &name)
 2 {
 3     CCASSERT(child != nullptr, "Argument must be non-nil");
 4     CCASSERT(child->_parent == nullptr, "child already added. It can‘t be added again");
 5
 6     addChildHelper(child, localZOrder, INVALID_TAG, name, false); //第一步
 7 }
 8
 9 void Node::addChildHelper(Node* child, int localZOrder, int tag, const std::string &name, bool setTag)
10 {
11     if (_children.empty())
12     {
13         this->childrenAlloc();
14     }
15
16     this->insertChild(child, localZOrder); //第二步
17
18     if (setTag)
19         child->setTag(tag);
20     else
21         child->setName(name);
22
23     child->setParent(this);
24     child->setOrderOfArrival(s_globalOrderOfArrival++);
25
26     if( _running )
27     {
28         child->onEnter();
29         // prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
30         if (_isTransitionFinished)
31         {
32             child->onEnterTransitionDidFinish();
33         }
34     }
35
36     if (_cascadeColorEnabled)
37     {
38         updateCascadeColor();
39     }
40
41     if (_cascadeOpacityEnabled)
42     {
43         updateCascadeOpacity();
44     }
45 }
1 // helper used by reorderChild & add
2 void Node::insertChild(Node* child, int z) 3 {
4     _transformUpdated = true;
5     _reorderChildDirty = true;
6     _children.pushBack(child); //第三步
7     child->_localZOrder = z;
8 }

_children是一个Vector容器(cocos2dx自己封装过的)它在pushBack的时候是这个样子

1  void pushBack(T object)
2     {
3         CCASSERT(object != nullptr, "The object should not be nullptr");
4         _data.push_back( object );
5         object->retain();  //在这里, 引用计数被加1
6     }

执行完addChild()之后,其引用计数为2

在当前帧执行完成时:

 1 void DisplayLinkDirector::mainLoop()
 2 {
 3     if (_purgeDirectorInNextLoop)
 4     {
 5         _purgeDirectorInNextLoop = false;
 6         purgeDirector();
 7     }
 8     else if (_restartDirectorInNextLoop)
 9     {
10         _restartDirectorInNextLoop = false;
11         restartDirector();
12     }
13     else if (! _invalid)
14     {
15         drawScene();
16
17         // release the objects
18         PoolManager::getInstance()->getCurrentPool()->clear();//在这里会清空自动释放池中的所有单位,即其引用计数-1
19     }
20 }

所以这个时候其引用计数为1。

在genMenuWnd析构的时候,会释放_children,此时调用Vector()的clear()

1  void clear()
2     {
3         for( auto it = std::begin(_data); it != std::end(_data); ++it ) {
4             (*it)->release();
5         }
6         _data.clear();
7     }

所以该节点的引用计数变为了0,此时会进行delete

时间: 2024-08-05 19:35:53

浅谈自己对cocos2dx的内存管理的理解的相关文章

cocos2dx 之内存管理

 cocos2dx的内存管理移植自Objective-C, 对于没有接触过OC的C++开发人员来说是挺迷惑的.不深入理解内存管理是无法写出好的C++程序的,我用OC和cocos2dx也有一段时间了,在此总结一下,希望对想用cocos2dx开发游戏的朋友有所帮助. C++的动态内存管理一般建议遵循谁申请谁释放的原则,即谁通过new操作符创建了对象,谁就负责通过delete来释放对象.如果对象的生命周期在一个函数内,这很容易做到,在函数返回前delete就行了.但一般我们在函数中new出来的对象

cocos2dx的内存管理机制

首先我们必须说一下c++中变量的内存空间的分配问题,我们在c++中写一个类,可以在栈上分配内存空间也可以使用new在堆上分配内存空间,如果类对象是在栈上分配的内存空间,这个内存空间的管理就不是我们的事了,但如果是在堆上分配的内存空间,当然需要我们来手动的delete了!cocos2dx采用的是在堆上分配内存空间,想想看你在写程序的时候对于cocos2dx中的类是不是大多数都是通过工厂方法获得的一个指针,你见过在栈上分配内存空间的情况吗?所以问题来了,既然在堆上分配内存空间,那么如何管理这个内存空

cocos2dx 使用过程中内存管理的理解

关于引擎内存管理的细节,网上有大量的详解,这里概括一下: cocos2d-x 的世界是基于 CCObject 类构建的,所以内存管理的本质就是管理一个个 CCObject. //CCObject 内部维护着一个引用计数,引用计数为 0 就自动释放 unsigned int m_uReference; //管理内存的实质就是管理这些 "引用计数" 了,使用 retain 和 release 方法对引用计数进行操作 void release(void);//引用计数:--m_uRefere

cocos2dx 内存管理的理解

关于引擎内存管理的细节,网上有大量的详解,这里概括一下: cocos2d-x 的世界是基于 CCObject 类构建的,所以内存管理的本质就是管理一个个 CCObject. //CCObject 内部维护着一个引用计数,引用计数为 0 就自动释放 unsigned int m_uReference; //管理内存的实质就是管理这些 “引用计数” 了,使用 retain 和 release 方法对引用计数进行操作 void release(void);//引用计数:--m_uReference v

Object-C内存管理的理解总结

今天看到了OC的内存管理这块,觉得很亲切. 自己的习惯是尽量自己掌控程序的空间和时间,有点强迫症的感觉.用C和C++做项目的时候,时时刻刻都在操心这new和delete的配对使用和计数,学习stl和boost的时候看到了智能指针等时候,依然不是很爱使用,还是愿意坚持自己控制new和delete:后来用C#后,一直特别注意Dispose相关的动作,尽早释放对象占有的内存空间,避免无谓的占用一直到程序退出才释放. OC中系统对每个实例对象地址都记录一个引用次数(当然有特例,见另外一篇随笔),这就是引

Python的内存管理 小理解

请看下面的一段代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 origin = {'a':100,'b':[1,2,34,5]} obj_copy ={}; print origin; obj_copy['key1']= origin; obj_copy['key2']= origin; print(obj_copy) print('我们试图改变obj_copy中某个Key值的内容') obj_copy['key1']['a'] = 10000 pri

Android开发:浅谈MVP模式应用与内存泄漏

最近博主开始在项目中实践MVP模式,却意外发现内存泄漏比较严重,但却很少人谈到这个问题,促使了本文的发布,本文假设读者已了解MVP架构. 本文原创作者:xiong_it,链接:http://blog.csdn.net/xiong_it MVP简介 M-Modle,数据,逻辑操作层,数据获取,数据持久化保存.比如网络操作,数据库操作 V-View,界面展示层,Android中的具体体现为Activity,Fragment P-Presenter,中介者,连接Modle,View层,同时持有modl

浅谈android应用性能之内存(转)

如何测试一个APP的内存占用情况?一个APP占用的内存分哪些部分?如何检查一个APP是否存在内存泄漏? 一.Android内存介绍: 在java开发过程中,是通过new来为对象分配内存的,而内存的释放是由垃圾收集器(GC)来回收的,在开发的过程中,不需要显式的去管理内存,java虚拟机会自动帮我们回收内存.但是这样有可能在不知不觉中就会浪费了很多内存,最终导致java虚拟机花费很多时间去进行垃圾回收,更严重的是造成JVM的OOM. 二.APP占用的内存分哪些 Android系统中的内存和linu

浅谈Atlassian产品搭建的敏捷管理体系(一)

Dream big, work smart, deliver fast 使用Atlassian的产品已经有三年多,但是大部分主要以JIRA和Confluence为主,今年年初加入一创业团队负责技术团队的搭建,从零开始通过部署Atlassian产品.制定开发流程,由于创业团队人手不够,自身也参与了大部分的开发工作,开始有一些考虑不周的地方,随着工作的展开不断调整,通过半年的努力也引来了第一轮的投资,可能创始人国企非技术出生背景的关系,在对技术团队的价值看待上分歧很大,最后还是选择了离开.机缘巧合,