Cocos2d-x 内存管理与数据结构

原创 2017年01月21日 21:33:21

Cocos2d-x 内存管理与数据结构

引用计数

Cocos采用的是引用计数的方式管理内存,Cocos会记录堆上每个对象被引用的次数,当引用次数为0时则自动释放内存。

 

Ref

为了实现对类引用次数的管理,Cocos的类都继承了Ref类。

class CC_DLLRef
{
public:
    voidretain();  //增加引用计数,当需要保存使用对象时,需要调用该函数增加引用计数
    voidrelease(); //减少引用计数,当引用计数减少到0时则时会释放内存
    Ref*autorelease(); //将内存加入自动释放内存池,下一次Application::run()的循环会调用一次对象的Release函数
    unsignedintgetReferenceCount() const;//获取引用次数
    virtual~Ref();  //虚析构函数保证派生类的析构函数被调用到
protected:
    Ref();//将构造函数设为保护属性,就无法直接实例化Ref类,new Ref()将报错
protected:
    unsignedint_referenceCount;//记录引用的次数
    friendclassAutoreleasePool;
};



AutoreleasePool

为了实现内存的自动释放AutoreleasePool创建了内存池,内存池会记录所有要自动释放的内存。

class CC_DLLAutoreleasePool
{
public:
    AutoreleasePool();
    AutoreleasePool(conststd::string&name);
    ~AutoreleasePool();
    void addObject(Ref *object);//将对象加入到自动管理内存池
    voidclear(); //清理内存
    boolcontains(Ref* object)const;//对象是否在内存池中
    voiddump(); //将内存池中的内对象信息输出到日子,方便调试
    
private:
    std::vector<Ref*>_managedObjectArray;
    std::string_name;
    
};

AutoreleasePool内存的释放

Main函数调用的Run函数的循环调用了director->mainLoop(),其每次绘制完后会清理内存

void DisplayLinkDirector::mainLoop()
{
    if(_purgeDirectorInNextLoop){
        _purgeDirectorInNextLoop= false;
        purgeDirector();
    }
    elseif(_restartDirectorInNextLoop){
        _restartDirectorInNextLoop= false;
        restartDirector();
    }
    elseif(! _invalid)
    {
        drawScene();
        //清理内存,对AutoreleasePool中的每个对象掉Ref::release函数
        PoolManager::getInstance()->getCurrentPool()->clear();
    }
}


 

引用内存的使用

new一个对象后引用计数为1,然后调用Ref::autorelease加入到自动管理内存池,对象会在下一次主循环时调用Ref::release如果需要保存对象一直使用则需要调用一次Ref::retain函数增加引用计数。例如:

//内部会调用 autorelease函数,create函数见下方代码
auto sprite = Sprite::create("HelloWorld.png"); 
this->addChild(sprite, 0);//内部会调用Ref::retain函数增加引用计数

Sprite* Sprite::create(const std::string& filename)
{
    Sprite *sprite = new (std::nothrow) Sprite();
    if (sprite && sprite->initWithFile(filename))
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

 

         为了方便和统一create的定义函数,Cocos提供了相CREATE_FUNC宏,在类中加入该宏及定义了create函数。

#defineCREATE_FUNC(__TYPE__) \
static__TYPE__* create() \
{\
    __TYPE__ *pRet = new(std::nothrow)__TYPE__(); \
    if (pRet&& pRet->init()) \
    { \
        pRet->autorelease();\
        returnpRet; \
    } \
    else \
    { \
        deletepRet; \
        pRet = nullptr;\
        returnnullptr;\
    } \
}


         例如:

classHelloWorld: public cocos2d::Layer
{
public:
    virtual boolinit();
    void menuCloseCallback(cocos2d::Ref*pSender);
    //定义静态create函数
    CREATE_FUNC(HelloWorld)
};
    auto layer= HelloWorld::create();//CREATE_FUNC宏定义的函数
    scene->addChild(layer);

 

 

 

Vector

CocosVector类是对C++ STL中的std::vector进行了一层封装,其只有一个变量    std::vector<T>_data;之所以要重新封装一层,是为了实现对引用计数内存的管理。

当向_data数组中添加数据时其会对调用对象的Ref:: retain函数增加引用计数,从_data中删除数据时会调用Ref::release函数减少引用计数释放释放内存。

 

例如pushback函数和popBack函数

    voidpushBack(T object)
    {
        CCASSERT(object != nullptr,"The object should not be nullptr");
        _data.push_back( object );
        object->retain();//增加引用计数
    }
    voidpopBack()
    {
        CCASSERT(!_data.empty(), "no objects added");
        autolast= _data.back();
        _data.pop_back();
        last->release();//减少引用计数释放内存
    }

 

Map

cocos2d::Map类是使用std::unordered_map作为底层结构的关联式容器。在关联式容器的基础上进行封装实现对引用计数内存的自动管理。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wlk1229/article/details/54647500

我所理解的Cocos2d-x Cocos2d-x 内存管理机制

C++内存管理C++显式堆内存管理性能上有一定优势,但有如下缺点: 野指针:指针指向的内容已经被释放,但是其他指针还可能指向它。 重复释放:重复释放一个已经释放的内存单元,或者释放一个野指针,都会导致...
  • sinat_24229853
  • sinat_24229853
  • 2016-07-21 15:15:03
  • 543

Cocos2d-x 3.0 内存管理机制

在C++中,动态内存分配是一把双刃剑,一方面,直接访问内存地址提高了应用程序的性能,与使用内存的灵活性;另一方面,由于程序没有正确地分配与释放造成的例如野指针,重复释放,内存泄漏等问题又严重影响着应用...
  • vinrex
  • vinrex
  • 2014-10-16 10:42:27
  • 5933

linux kernel内存管理数据结构

mem_map 是一个全局变量, 指向一个struct page数组, 管理着系统中的所有物理页面, 数组中的每个page结构,对应一个物理页框. mem_map仅当系统为单NODE时有效 N...
  • kickxxx
  • kickxxx
  • 2017-01-23 20:01:44
  • 1091

cocos2d-x的内存管理

内存管理是移动开发的非常重要的部分,控制不好很容易就爆内存。而内存引起的当机,在后面排查的时候是最麻烦的事情。 cocos2d-x的内存管理是模仿oc的引用计数方法。据说3.0在设计时,有讨论到底是...
  • ff_csdn
  • ff_csdn
  • 2014-02-10 16:36:32
  • 1077

Cocos2d-lua 内存管理

Cocos2d-x的核心框架是由C++来实现的,然后通过LuaBinding转化为Lua API。 Cocos2d-x引擎中的对象被创建后,使用retain和release来管理对象的生命周期,结合A...
  • Register_man
  • Register_man
  • 2017-08-29 17:08:40
  • 1688

linux内存管理之数据结构

linux内存管理之数据结构linux内存管理之数据结构 一物理空间管理 1 页表项 2 物理页面管理对象page 二内存分区 1 过去的分区 2 当下的分区情况 三 虚拟空间管理 1 进程虚存区域 ...
  • u013298300
  • u013298300
  • 2016-04-21 23:46:31
  • 3557

cocos2dx内存管理解析

今天第一天开始写博客,我想我也会一直的坚持坚持下去,和所有人进行分享和交流,这也是源于对技术的热爱和对游戏的炽热,我想我的这一生都将会奉献给游戏,他是我一辈子的事业更是我这辈子的朋友,好了废话就不多说...
  • jiangtao_killer
  • jiangtao_killer
  • 2015-03-31 00:02:51
  • 1021

Linux内存管理数据结构之间的关系

linux内存管理是一个相当复杂的机制,这里只是基础的内存管理知识结构,不包括页面换出换入。 可以从以下角度思考问题 用户地址空间: 用户内存请求被认为是不紧迫的 用户访问是危险的 权限控制用...
  • wyg_031113
  • wyg_031113
  • 2016-03-21 22:04:07
  • 497

cocos2d-x学习之内存管理01:概述

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://goldlion.blog.51cto.com/4127613/784134 ...
  • qq_29050863
  • qq_29050863
  • 2017-08-17 08:52:38
  • 198

Cocos2d-Lua(Quick-Cocos2d-x)内存优化

转载于:http://www.cnblogs.com/zhangfeitao/p/4562791.html 前言   对于内存的优化,网上有很多例子和教程。总体来说,就那么...
  • qq_30392565
  • qq_30392565
  • 2017-02-20 16:53:41
  • 1136
收藏助手
不良信息举报
您举报文章:Cocos2d-x 内存管理与数据结构
举报原因:
原因补充:

(最多只允许输入30个字)