cocos中所有的对象都是继承自Ref基类,Ref的职责就是对对象进行引用计数管理

内存管理中最重要的是三个方法retain()、release()、autorelease()

在cocos中创建对象的标准流程是:

创建对象->初始化->添加到自动内存管理->返回创建成功的对象

就比如下面这段代码1:创建Node对象

//代码1
Node * Node::create()
{
Node * ret = new (std::nothrow) Node();
if (ret && ret->init())
{
ret->autorelease();
}
else
{
CC_SAFE_DELETE(ret);
}
return ret;
}

在代码1中,我们只需要调用create方法就可以实现创建对象、初始化和自动管理内存。

在cocos中有的函数中直接使用了create的宏定义,调用对象的create方法就可以执行代码2,实现的功能和代码1是一样的。

//代码2
#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
__TYPE__ *pRet = new(std::nothrow) __TYPE__(); \
if (pRet && pRet->init()) \
{ \
pRet->autorelease(); \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = nullptr; \
return nullptr; \
} \
}

代码2中调用autorelease方法,将对象加入自动内存管理池自动管理。

代码3是autorelease方法的实现

//代码3
Ref* Ref::autorelease()
{
PoolManager::getInstance()->getCurrentPool()->addObject(this);
return this;
}

首先看一下代码4,PoolManager的getInstance方法

在代码4中创建了PoolManager对象并调用了this的AutoreleasePool方法(代码5)

"cocos2d autorelease pool"是这个自动管理池的name

//代码4
PoolManager* PoolManager::getInstance()
{
if (s_singleInstance == nullptr)
{
s_singleInstance = new (std::nothrow) PoolManager();
// Add the first auto release pool
new AutoreleasePool("cocos2d autorelease pool");
}
return s_singleInstance;
}

在代码5中可以看到先是对_managedObjectArray预留空间,然后将this加了进去

//代码5
AutoreleasePool::AutoreleasePool(const std::string &name)
: _name(name)
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
, _isClearing(false)
#endif
{
_managedObjectArray.reserve(150);
PoolManager::getInstance()->push(this);
}

在代码3中还调用了getCurrentPool方法用来获取当前的内存管理池

//代码6
AutoreleasePool* PoolManager::getCurrentPool() const
{
return _releasePoolStack.back();
}

然后把this加入到当前的内存管理池中作为一个ref对象进行管理,如代码7

//代码7
void AutoreleasePool::addObject(Ref* object)
{
_managedObjectArray.push_back(object);
}

整个流程如下图所示

自动内存管理的结构如下图,用一个栈来存储多个自动内存管理池,在自动内存管理池中又有若干个ref对象。

在内存管理中主要是靠引用计数来记录对象的使用情况,当一个对象被create时会给它分配内存,并且会调用retain()方法让引用计数+1;当调用release()时会让引用计数-1,release时会检查引用计数是否为0,引用计数为0时会调用delete删除对象并释放内存。

在每一帧结束时会清理当前的内存管理池,将每一个ref对象的引用计数都-1,这帧结束之后,内存管理池中就没有这个ref对象了,引用计数是ref自己的属性,当下一次被release时如果引用计数=0,就会被释放。

void Director::mainLoop()
{
......
PoolManager::getInstance()->getCurrentPool()->clear();
}
}
void AutoreleasePool::clear()
{
std::vector<Ref*> releasings;
releasings.swap(_managedObjectArray);
for (const auto &obj : releasings)
{
obj->release();
}
}

retain()和release()只是帮助我们记录一个对象的引用次数,在程序中几乎不用手动调用。

从零开始のcocos2dx生活(一)内存管理的更多相关文章

  1. Cocos2d-x 3.1 内存管理机制

    Cocos2d-x使用的内存管理方式是引用计数.引用计数是一种非常有效的机制.通过给每个对象维护一个引用计数器,记录该对象当前被引用的次数.当对象添加一次引用时,计数器加1:而对象失去一次引用时.计数 ...

  2. cocos2dx中的内存管理机制及引用计数

    1.内存管理的两大策略: 谁申请,谁释放原则(类似于,谁污染了内存,最后由谁来清理内存)--------->适用于过程性函数 引用计数原则(创建时,引用数为1,每引用一次,计数加1,调用结束时, ...

  3. 菜鸟学习Cocos2d-x 3.x——内存管理

    菜鸟学习Cocos2d-x 3.x——内存管理 2014-12-10 分类:Cocos2d-x / 游戏开发 阅读(394) 评论(6)    亘古不变的东西 到现在,内存已经非常便宜,但是也不是可以 ...

  4. cocos2dx中的内存管理方式

    转载:http://www.cocoachina.com/bbs/read.php?tid=195219 今天看了一下cocos2dx的内存管理机制,有些地方不太好理解搞了挺长的时间,现在感觉自己理解 ...

  5. cocos2d-x 3.0 内存管理机制

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  6. 【转】cocos2d-x与ios内存管理分析(在游戏中减少内存压力)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=281 注:自己以前也写过coco ...

  7. cocos2d-x与ios内存管理分析(在游戏中减少内存压力)

    转自:http://www.cocos2dev.com/?p=281 注:自己以前也写过cocos2d-x如何优化内存的使用,以及内存不足的情况下怎么处理游戏.今天在微博中看到有朋友介绍了下内存,挺详 ...

  8. cocos2d-x与ISO内存管理(转)

    一,IOS与图片内存 在IOS上,图片会被自动缩放到2的N次方大小.比如一张1024*1025的图片,占用的内存与一张1024*2048的图片是一致的.图片占用内存大小的计算的公式是:长*宽*4.这样 ...

  9. 从零开始のcocos2dx生活(二)Node

    节点 Node 文章目录 节点 Node 前言 变量初始化 创建一个节点对象 获取节点依赖的计数器 获取节点的描述(获取节点的Tag) 节点的局部层顺序值(LocalZOrder) 设置节点的Loca ...

随机推荐

  1. 转载:ubuntu 下的dpkg 的用法

    dpkg是一个Debian的一个命令行工具,它可以用来安装.删除.构建和管理Debian的软件包. 下面是它的一些命令解释: 1)安装软件 命令行:dpkg -i <.deb file name ...

  2. 逗号分隔的字符串转换为Python中的列表 split

    将逗号分隔的字符串转换为Python中的列表   给定一个字符串: 它是由逗号分隔的几个值的序列: mStr = '192.168.1.1,192.168.1.2,192.168.1.3' 如何将字符 ...

  3. WPS修订功能的使用

    WPS设置 设置用户名: 修改之后的效果:

  4. OpenStack☞网关协议

    一 动态页面与静态页面区别 静态页面:每一个网页都有一个固定的URL,且网页的URL以.html..htm..shtml等常见的形式为后缀. 网页内容已经发布到网站服务器上,无论是否有用户访问,每个静 ...

  5. APICloud修改最低操作系统版本要求

    在APICloud中的云编译选项中: 点击高级设置,就可以修改对应的操作系统版本要求:

  6. 【codeforces 520C】DNA Alignment

    [题目链接]:http://codeforces.com/contest/520/problem/C [题意] 给你一个函数; 它的作用是评估两个字符串的相似程度; 评估的时候: 保持一个字符串不动, ...

  7. 最短路径Dijkstra算法和Floyd算法整理、

    转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径—Dijkstra算法和Floyd算法 Dijks ...

  8. Json介绍与Ajax技术

    AJAX   AJAX准备知识:JSON 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据 ...

  9. vue echarts引用

    <template> <!--为echarts准备一个具备大小的容器dom--> <div id="main" style="width: ...

  10. php_sphinx安装使用

    Sphinx的简介: Sphinx是一个独立的全文索引引擎,意图为其他应用提供高速.低空间 占用.搜索结果高相关度的全文搜索功能.Sphinx可以非常容易的与 SQL数据库和脚本语言集成.内置MySQ ...