一.自动内存管理

1)概述

C++语言默认是没有提供自动内存管理的。使用者需要自己分配,自己释放。在cocos2d-x里提供了一个自动内存管理的方案。主要是通过CCObject来提供的,用户只要继承了CCObject,就可以通过调用autorelease()来告诉系统进行自动内存管理。

一般用法就是:    CCLayer* pLayer = CreateLayer(s_nActionIdx);    pLayer->autorelease();

2)自动内存管理的实现

自动内存管理的实现原理大概是:用户设置自动释放功能时,内存管理(CCPoolManager)会自动把这个CCObject对象加入其管理池中。等到一定时机(场景销毁,一帧渲染结束,程序退出等),内存管理会遍历其所管理的每一个对象,逐个调用CCObject的释放函数进行释放。CCObject自己内部设置一个引用系数,增加一个使用就系数加一,释放就系数减一,当系数为0时,才真正进行释放。

如果研究下CCPoolManager,会发现进行真正内存管理的是自动释放池(CCAutoreleasePool),CCPoolManager下面包含有多个CCAutoreleasePool。CCAutoreleasePool提供了addObject,removeObject,clear功能。我开始很疑惑,因为进行内存释放管理,一个CCAutoreleasePool就够了。后来仔细考虑,发现了这个的秘密所在:

CCPoolManager管理多个CCAutoreleasePool,是为了方便确定哪个自动释放池(CCAutoreleasePool)可以进行释放,而不用影响到其他的自动释放池。比如在关卡切换时,上一个关卡的自动释放池的数据就可以进行自动释放了,而新关卡的自动释放池不变~~ 好想法!

二、引用计数器——手动管理内存

CCObject的及其子类的对象在创建时,引用计数自动设置为1。之后每次调用retain,引用计数+1。每次调用release,引用计数-1;若引用计数=0,则直接delete this。
相关接口如下:
 
  1. //引用次数+1
  2. virtual void CCObject::retain(void);
  3. //引用次数-1;若引用计数器=0,则delete this;
  4. virtual void CCObject::release(void);
  5. //helper方法,快速判断当前对象只有唯一引用
  6. bool CCObject::isSingleRefrence(void);
  7. //返回引用次数
  8. unsigned int CCObject::retainCount(void);
 
原则1:谁生成(new、copy)谁负责release。
例子:
  1. CCObject *obj=new CCObject;
  2. ...
  3. obj->release();
 
retain是在指针传递和赋值时使用的,他的含义是表示拥有。这经常用在指针赋值上。
原则2:谁retain,谁负责release。
例子:
  1. obj->retain();
  2. ...
  3. obj->release();
 
原则3:传递赋值时,需要先retain形参,后release原指针,最后赋值。(注意,因为这里没有使用自赋值检查,所以这组顺序不能错。)
例子:
  1. void CCNode::setGrid(CCGridBase* pGrid)
  2. {
  3. CC_SAFE_RETAIN(pGrid);
  4. CC_SAFE_RELEASE(m_pGrid);
  5. m_pGrid = pGrid;
  6. }
 
 
三、自动释放池——自动管理内存
 
原则4:对于使用autorelease的对象,不必管它,每帧结束后会自动释放。
 

相关接口:

 
  1. CCObject* CCObject::autorelease(void);
 
例子:
  1. CCObject *obj=new CCOjbect;
  2. obj->autorelease();
  3. ...
完全手动管理内存,很繁琐,cocos2d-x提供了自动释放池CCPoolManager。将对象置于自动释放池中,每帧绘制结束,就自动release池中的对象。
四、CCNode节点管理
 
cocos2d-x使用节点组成一棵树,渲染的时候要遍历这棵树。CCNode是所有节点类的父类,他内部使用了一个CCArray对象管理他的所有子节点,当对象被添加为子节点时,实际上是被添加到CCArray对象中,同时会调用这个对象的retain方法。同理,从CCArray中移除时,也会调用release方法。
 
相关接口:
  1. virtual void addChild(CCNode * child);
  2. virtual void addChild(CCNode * child, int zOrder);
  3. virtual void addChild(CCNode * child, int zOrder, int tag);
  4. virtual void removeChild(CCNode* child, bool cleanup);
  5. void removeChildByTag(int tag, bool cleanup);
  6. virtual void removeAllChildrenWithCleanup(bool cleanup);
 
在切换场景时,系统会遍历整棵树的节点,进行release。
 
五、静态工厂
 
cocos2d-x中存在大量的静态工厂方法,这些方法中,全都对this指针调用了autorelease函数。如CCSprite中的这些方法:
  1. static CCSprite* spriteWithTexture(CCTexture2D *pTexture);
  2. static CCSprite* spriteWithTexture(CCTexture2D *pTexture, const CCRect& rect);
  3. static CCSprite* spriteWithTexture(CCTexture2D *pTexture, const CCRect& rect, const CCPoint& offset);
  4. static CCSprite* spriteWithSpriteFrame(CCSpriteFrame *pSpriteFrame);
  5. static CCSprite* spriteWithSpriteFrameName(const char *pszSpriteFrameName);
  6. static CCSprite* spriteWithFile(const char *pszFileName);
  7. static CCSprite* spriteWithFile(const char *pszFileName, const CCRect& rect);
  8. static CCSprite* spriteWithBatchNode(CCSpriteBatchNode *batchNode, const CCRect& rect);
 
这些方法内部实现了:内存分配、初始化、设置autorelease。用静态工厂来生成对象,可以简化代码,是官方建议的方法。
 
六、cache机制类
 
cocos2d-x中存在一些cache类,这些都是单例类的管理器。
 
 
这些cache内部也使用了ratain和release方法,防止这些资源被释放掉。
使用这些cache,我们可以保存预加载的一些资源,在方便的时候调用它,去绑定给一些对象。注意,这些cache在场景切换时,不会自动删除,需要手动调用purgeXXXX方法,进行清理。

cocos2d-x学习之自动内存管理的更多相关文章

  1. JVM自动内存管理学习笔记

    对于使用 C.C++ 的程序员来说,在内存管理领域,他们既是拥有最高权力的皇帝又是从事最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任.对于 Java 程 ...

  2. Xcode 如何设置 自动内存管理 转换为 手动内存管理

    建议使用自动内存管理 ARC. 如果不想自动内存管理,可以在build phases 下的compile sources 中找到不想自动管理的.m文件 ,给它加compiler flags 为 -fn ...

  3. JVM自动内存管理机制--读这篇就GO了

    之前看过JVM的相关知识,当时没有留下任何学习成果物,有些遗憾.这次重新复习了下,并通过博客来做下笔记(只能记录一部分,因为写博客真的很花时间),也给其他同行一些知识分享. Java自动内存管理机制包 ...

  4. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

  5. 深入理解Java虚拟机(自动内存管理机制)

    文章首发于公众号:BaronTalk 书籍真的是常读常新,古人说「书读百遍其义自见」还是很有道理的.周志明老师的这本<深入理解 Java 虚拟机>我细读了不下三遍,每一次阅读都有新的收获, ...

  6. iOS----ARC(自动内存管理)

    1.ARC是什么呢,有什么用? ARC是苹果官方推出的帮助我们苹果开发工程师管理内存的一种自动内存管理机制,它的前身是MRC,也就是手动内存管理: 2.ARC的基本原理是什么? ARC是编译器(时)特 ...

  7. 垃圾回收算法手册:自动内存管理的艺术 BOOK

    垃圾回收算法手册:自动内存管理的艺术 2016-03-18 华章计算机 内容简介 PROSPECTUS 本书是自动内存管理领域的里程碑作品,汇集了这个领域里经过50多年的研究沉积下来的最佳实践,包含当 ...

  8. 【IOS学习基础】内存管理

    1.内存几大区域 1> 栈区:局部变量(基本数据类型.指针变量). 2> 堆区:程序运行的过程中动态分配的存储空间(创建的对象). 3> BSS段:没有初始化的全局变量和静态变量. ...

  9. JVM自动内存管理-Java内存区域与内存溢出异常

    摘要: JVM内存的划分,导致内存溢出异常的可能区域. 1. JVM运行时内存区域 JVM在执行Java程序的过程中会把它所管理的内存划分为以下几个区域: 1.1 程序计数器 程序计数器是一块较小的内 ...

随机推荐

  1. 安卓动画之ObjectAnimator

    ObjectAnimator 不仅仅移动位置,还移动了对象view 先来代码片段: //Y轴变换 ObjectAnimator oa = ObjectAnimator.ofFloat(imageVie ...

  2. BITED数学建模七日谈之六:组队建议和比赛流程建议

    今天进入数学建模经验谈第六天:组队建议和比赛流程建议 数学模型的组队非常重要,三个人的团队一定要有分工明确而且互有合作,三个人都有其各自的特长,这样在某方面的问题的处理上才会保持高效率. 三个人的分工 ...

  3. C# html互转mht

    using System;using System.Runtime.InteropServices;using System.Text;using System.IO;namespace HTMLCo ...

  4. Java WEB —— Java提升

    Java 5.0新特性: 枚举: enum Grade{ --> 相当于类 A("80~100"),B("70~80"),C("60~70&qu ...

  5. 第一百九十三天 how can I 坚持

    我以为我是谁. 你可以记录你今天看了电影 也可以记录你最近在听什么歌 但这都会成为回忆 .  ---oncelife 快受不了了啊.咋办. 今天看了<滚蛋吧,肿瘤君>,还看了<那山那 ...

  6. HTML5简介及HTML5的发展前景

    WEB技术发展越来越迅速,HTML5的到来更是把WEB技术推向了巅峰,目前HTML5技术已经日趋成熟,不仅在PC段,HTML5更是在移动终端上也有广泛的应用,HTML5的未来十分光明,值得我们去学习. ...

  7. android打电话、发短信实现

    打电话: Intent intent = newIntent(Intent.ACTION_CALL,Uri.parse("tel:"+"156666666666" ...

  8. 使用Canvas把照片转换成素描画

    原文:http://www.alloyteam.com/2012/07/convert-picture-to-sketch-by-canvas/ 腾讯的alloy team写的一个素描效果,挺不错的. ...

  9. Server-U与IIS端口占用问题解决

    在新版的ftp软件Server-U(11.X)中,由于其默认设置中监听了80端口,经常会导致IIS不能服务不能正常启用,下面记录如何修改server-u的80端口.     打开Server-U软件, ...

  10. Oracle中的NVL,NVL2,NULLIF以及COALESCE函数使用

    首先注意空(null)值,空值加任何值都是空值,空值乘任何值也都是空值,依此类推. 1.NVL函数 NVL函数的格式如下:NVL(expr1,expr2) 含义是:如果oracle第一个参数为空那么显 ...