从源代码版本号3.x。转载请注明

cocos2d-x 总的文件夹的源代码分析:

http://blog.csdn.net/u011225840/article/details/31743129

1.Ref,AutoreleasePool。PoolManager

Ref中包括了一个叫referenceCount的引用计数,当一个Ref类的变量被new的时候,其referenceCount的引用计数被置为1。 当中有三个重要的操作,retain。release,autorelease,以下源代码分析时会具体说明。
        AutoreleasePool中存放在被显示调用autorealse的ref。而且在每一帧过后调用其clear函数。显示的调用存放在当中的ref的realse函数,然后清空自身。
        PoolManager则管理着所欲的AutoreleasePool,没有错,不唯独一个AutoreleasePool,有多个AutoreleasePool。

2.源代码分析

         假设你想清晰的了解cocos2d-x 3.x 的内存管理机制。请你一定要耐心阅读完这里的代码,源码本身清晰易懂,何况我已经加了一些必要的中文凝视呢~

2.1 Ref源代码分析

          重要的成员变量:_referenceCount,在构造函数中被置为1,切记。

          
         
void Ref::retain()
{
CCASSERT(_referenceCount > 0, "reference count should greater than 0");
++_referenceCount;
}
Ref* Ref::autorelease()
{
PoolManager::getInstance()->getCurrentPool()->addObject(this);
return this;
}
void Ref::release()
{
CCASSERT(_referenceCount > 0, "reference count should greater than 0");
--_referenceCount;
if (_referenceCount == 0)
{
delete this;
}
}

当中一些Debug或者追踪memory leak 的宏和函数我已经去掉,事实上这三个函数的本质就是这么简单,retain和release分别添加和降低referenceCount,而且release函数在count为0时就delete 自己。autorelease函数将Ref放入当前的AutorealsePool。

         Attention Please:三个函数内部都有一个CCASSERT。要求调用时该object的referenceCout必须是大于0的。
                                           release或者autorealse必须和new或者retain成对出现。


         这里開始讲一下主要的使用方法。由于我们平时须要我们管理的、使用的类一般都是继承于Node(Layer、Sprite等)。看下Node的create函数吧。
         在Node的create中,调用了new(Count设置为1)后,马上调用了autoRelease,将其放入AutoreleasePool中。

(AutoreleasePool的源代码一会再分析)

         所以当你使用了create之后,请不要在使用release或者Autorelease,除非你手动了retain一次。

         可是当你把一个node1添加到还有一个node2的时候。你能够理解为此时node1的refereneceCount添加了一次,可是你不须要做不论什么额外的操作。由于当node1被remove或者即使没有remove操作。当node2析构的时候(会将他的child的count减1)。也就是说,整个引擎会自己主动管理referenceCount。仅仅要你不要手动的retain。



2.2AutoreleasePool 源代码分析

         
void AutoreleasePool::clear()
{
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
_isClearing = true;
#endif
for (const auto &obj : _managedObjectArray)
{
obj->release();
}
_managedObjectArray.clear();
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
_isClearing = false;
#endif
}

AutoRealse的clear函数十分清晰,就是调用其包括的ref的release函数,然后将自己的managedObject清空。这里须要解决的疑惑是何时调用了clear函数。打开Director的源代码
void DisplayLinkDirector::mainLoop()
{ if (_purgeDirectorInNextLoop)
{
_purgeDirectorInNextLoop = false;
purgeDirector();
}
else if (! _invalid)
{
drawScene(); // release the objects
PoolManager::getInstance()->getCurrentPool()->clear();
}
}

在你的App执行时,每一帧開始时都是先drawScene()。各种界面上的显示结束后,就開始clear了。


2.3 PoolManager

        std::deque<AutoreleasePool*> _releasePoolStack;

        AutoreleasePool *_curReleasePool;
        PoolManager管理着全部的autorerealsePool,而且有一个指针指向当前的releasePool。
        值得注意的是。笔者觉得3.x此处有个小bug。
        
PoolManager* PoolManager::getInstance()
{
if (s_singleInstance == nullptr)
{
s_singleInstance = new PoolManager();
// Add the first auto release pool
s_singleInstance->_curReleasePool = new AutoreleasePool("cocos2d autorelease pool");
s_singleInstance->_releasePoolStack.push_back(s_singleInstance->_curReleasePool);
}
return s_singleInstance;
}

poolManager是单例模式,当第一次初始化的时候,会自己主动生成一个AutoreleasePool,并将其放入自己的stack中。可是。当你打开AutoreleasePool的构造函数时,发现当中已经有一个调用PoolManager::getInstance()->push(this); 通过debug跟踪。笔者发现此时有两个AutoRealsePool。即poolManager的stack内有两个位置都指向同一个AutoRealsePool。

感觉此处应该是一个Bug。

3. 小结

        1.Ref,AutorealsePool。PoolManager是紧密相关的
        2.Ref的retain、new  应该与 release或者autoRealse成对出现。
        3.Node用途。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

cocos2d-x 源代码分析 : Ref (CCObject) 源代码分析 cocos2d-x内存管理策略的更多相关文章

  1. spark 源码分析之二十二-- Task的内存管理

    问题的提出 本篇文章将回答如下问题: 1.  spark任务在执行的时候,其内存是如何管理的? 2. 堆内内存的寻址是如何设计的?是如何避免由于JVM的GC的存在引起的内存地址变化的?其内部的内存缓存 ...

  2. spark 源码分析之十五 -- Spark内存管理剖析

    本篇文章主要剖析Spark的内存管理体系. 在上篇文章 spark 源码分析之十四 -- broadcast 是如何实现的?中对存储相关的内容没有做过多的剖析,下面计划先剖析Spark的内存机制,进而 ...

  3. Redis 内存管理 源码分析

    要想了解redis底层的内存管理是如何进行的,直接看源码绝对是一个很好的选择 下面是我添加了详细注释的源码,需要注意的是,为了便于源码分析,我把redis为了弥补平台差异的那部分代码删了,只需要知道有 ...

  4. redis 源代码分析(一) 内存管理

    一,redis内存管理介绍 redis是一个基于内存的key-value的数据库,其内存管理是很重要的,为了屏蔽不同平台之间的差异,以及统计内存占用量等,redis对内存分配函数进行了一层封装,程序中 ...

  5. Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析

    Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...

  6. 分析 JUnit 框架源代码

    本文转载至http://www.ibm.com/developerworks/cn/java/j-lo-junit-src/ 分析 JUnit 框架源代码 理解 JUnit 测试框架实现原理和设计模式 ...

  7. 读书摘要观后感与总结:《Glibc内存管理:ptmalloc2源代码分析》

    更新中 在Linux平台下做漏洞利用的时候,针对于Heap部分总是有些不求甚解,下面开个博文来记录下<Glibc内存管理:ptmalloc2源代码分析>这本书的读后感和收获,一些简单的点将 ...

  8. 【Java收集的源代码分析】Hashtable源代码分析

    Hashtable简单介绍 Hashtable相同是基于哈希表实现的,相同每一个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时.相同会自己主动增长. Has ...

  9. MySQL系列:innodb源代码分析之内存管理

    在innodb中实现了自己的内存池系统和内存堆分配系统,在innodb的内存管理系统中,大致分为三个部分:基础的内存块分配管理.内存伙伴分配器和内存堆分配器.innodb定义和实现内存池的主要目的是提 ...

随机推荐

  1. Booth算法

    Booth算法 算法描述(载自维基百科) 对于N位乘数Y,布斯算法检查其2的补码形式的最后一位和一个隐含的低位,命名为y-1,初始值为0.对于yi, i = 0, 1, ..., N - 1,考察yi ...

  2. Android的事件分发

    1. Touch事件和绘制事件的异同之处 Touch事件和绘制事件非常相似,都是由ViewRoot派发下来的,可是不同之处在绘制事件是由应用中的某个View发起请求,一层一层上传到ViewRoot.再 ...

  3. Android百日程序:GridView实现相冊效果

    本章使用GridView控件来做一个相冊效果. 图片效果例如以下: 响应点击事件,点击的时候提示是当前第几章图片.从左到右,从上到下. 点击了第一张图片,显示了1. 步骤: 一 新建项目,然后把图片资 ...

  4. thinkphp将excel导入到数据库中

    首先下载phpexcel插件 http://pan.baidu.com/s/1hq56dFm 我用的是thinkphp框架的3.1版本,下载好压缩包,框架中的extend中的vendor文件夹中新建一 ...

  5. [Grid Layout] Use the repeat function to efficiently write grid-template values

    We can use the repeat() function if we have repeating specifications for columns and rows. With the  ...

  6. 百度echarts可以做什么

    百度echarts可以做什么 一.总结 一句话总结:可视化做的很好,各种图都有.而且支持动态数据. 二.百度eCharts体验 前言 从昨天开始给项目里添加一些图表对比功能,上一个项目里使用的是Hig ...

  7. php中读取文件内容的几种方法。(file_get_contents:将文件内容读入一个字符串)

    php中读取文件内容的几种方法.(file_get_contents:将文件内容读入一个字符串) 一.总结 php中读取文件内容的几种方法(file_get_contents:将文件内容读入一个字符串 ...

  8. 如何安全退出多个Activity

    我们在项目开发的时候可能会遇到安全退出应用的场景,如何能够安全退出多个Activity?网上有很多方法,如下: 1.抛异常退出 该方法通过抛异常,使程序Force Close.验证可以,但是,需要解决 ...

  9. 【机器学习实战】第12章 使用 FP-growth 算法来高效发现频繁项集

    第12章 使用FP-growth算法来高效发现频繁项集 前言 在 第11章 时我们已经介绍了用 Apriori 算法发现 频繁项集 与 关联规则.本章将继续关注发现 频繁项集 这一任务,并使用 FP- ...

  10. 【物理】概念的理解 —— Phase(相位)

    Phase is the position of a point in time (an instant) on a waveform cycle. 相位指的是波形周期中点在某一时刻的位置.Phase ...