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. Python基础:12函数细节

    一:返回值 当没有显式地返回元素时,Python 会返回一个None.如果函数返回多个对象,python 把他们聚集起来并以一个元组返回. 二:创建函数 1:强烈推荐,在函数体之前,编写函数的文档字符 ...

  2. GitOps:Kubernetes多集群环境下的高效CICD实践

    为了解决传统应用升级缓慢.架构臃肿.不能快速迭代.故障不能快速定位.问题无法快速解决等问题,云原生这一概念横空出世.云原生可以改进应用开发的效率,改变企业的组织结构,甚至会在文化层面上直接影响一个公司 ...

  3. shell不排序去重

    一条命令搞定:   awk '!a[$0]++' file 如果是第一次出现a[$0]++的值为0(假),而!a[$0]++的值就为1(真),之后就执行print $0 第二次或者两次以上的出现a[$ ...

  4. jQuery Callback

    Callback 函数在当前动画 100% 完成之后执行. jQuery 动画的问题 许多 jQuery 函数涉及动画.这些函数也许会将 speed 或 duration 作为可选参数. 例子:$(& ...

  5. Python错误:AttributeError: 'generator' object has no attribute 'next'解决办法

    今天在学习生成器对象(generation object)运行以下代码时,遇到了一个错误: #定义生成器函数def liebiao(): for x in range(10): yield x#函数调 ...

  6. Android图形子系统

    图形操作可以有两种方式实现:一是利用通用CPU模拟图形操作:二是利用GPU专门做图形操作.前者会增加CPU的负担,在现在高分辨率已经是普遍现象的时候,让通用处理器来完成大量的图形计算已经不现实.And ...

  7. oracle的group by用法

    原文链接:https://www.cnblogs.com/Each-Person-Got-a-Dream/p/8946961.html sql如下: select min(es.sku_price) ...

  8. HMM(隐马尔科夫)用于中文分词

    隐马尔可夫模型(Hidden Markov Model,HMM)是用来描述一个含有隐含未知参数的马尔可夫过程. 本文阅读了2篇blog,理解其中的意思,附上自己的代码,共同学习. 一.理解隐马尔科夫 ...

  9. 【原生JS】图片预加载之有序预加载

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  10. .gitkeep常用写法

    # win & OSX system files .DS_Store Thumbs.db ehthumbs.db Desktop.ini # IDE files .idea # project ...