cocos2d-x内存管理(一)

原文来自:http://blog.csdn.net/a7833756/article/details/7628328

这篇文章写得很详细..

前言:c++内存机制,采用new关键字实例化的对象,必须在不使用的时候手动delete掉,否则new的时候开辟的内存就不能被回收,造成内存泄露。

我们来举个例子说明一下:

cocos2d-x内存管理(一)_第1张图片  

  运行 结果,vld工具提示了存在内存泄露:

cocos2d-x内存管理(一)_第2张图片


当加上delete操作后:



下面步入正题:

1、cocos2d-x 内存管理的方式,cocos2d-x采用引用计数的方式进行内存管理,当一个对象的引用计数为0的时候,就会被引擎自动delete掉。

所有cocos2d-x里面的类都继承ccobject类(应该是吧、),下面看ccobject类源码:

cocos2d-x内存管理(一)_第3张图片


这里 m_uReference 就是引用计数,在对象构造的时候,m_uReference置为1

cocos2d-x内存管理(一)_第4张图片


然后每次对对象进行retain操作,reference+1

cocos2d-x内存管理(一)_第5张图片

   

每次对对象进行release操作,reference-1,如果reference在这次release之后变为0,那么delete掉它

cocos2d-x内存管理(一)_第6张图片


2、以上是内存管理的基本原则,下面来讲引擎中是怎么对对象进行自动管理(autorelease)的。

我们以一个CCNode的生命历程为例,来讲一下自动管理的整个过程:

首先创建一个CCNode:

cocos2d-x内存管理(一)_第7张图片

CCNode对象被new出来之后,立刻执行autorelease操作,我们来进行跟踪:cocos2d-x内存管理(一)_第8张图片


可以看到,首先将m_bManaged置为true,表示处于自动管理状态,然后加入自动管理池,继续跟踪:



getCurReleasePool() 返回一个 CCAutoreleasePool 对象指针,也就是一个自动释放池,那么我们先去看看这个自动释放池里面有什么:

cocos2d-x内存管理(一)_第9张图片

首先就是一个ccobject数组,m_pManagedObjectArray , 这个数组放的就是接受自动释放的对象,也就是说,进行autorelease的对象,最终被放到它里面去了cocos2d-x内存管理(一)_第10张图片

那我们注意一下这里,m_pManagedObjectArray 是一个 CCMutableArray 对象,它的addobject()方法除了把一个对象放到这个array里面去,还做了什么呢,我们来看看源码:

cocos2d-x内存管理(一)_第11张图片


大家应该看到了,进行了一次retain()操作,使得对象的引用+1,那么对象在被add到这个array里之后,引用应该为2(不考虑其他地方进行的retain),所以在此之后立刻进行了一次release(),使得这次add造成的引用取消,这样一来,对象从创建开始引用为1,到现在被放进自动释放池中后,引用依然为1,同时,被管理状态为true。

那么我再进行深入的分析一下

getCurReleasePool()->addObject(pObject);

  里面的getCurReleasePool()方法,注意这个方法是 CCPoolManager 的方法:

cocos2d-x内存管理(一)_第12张图片

那么我看到 CCPoolManager 类,顾名思义,我们也想得到它是对自动释放池进行管理的类,这是个全局变量,在main()函数执行之前由系统自动调用其默认构造方法进行实例化。下面进入这个类去看看里面有些什么:

cocos2d-x内存管理(一)_第13张图片

我们发现了,里面有一个 CCAutoreleasePool 对象 m_pCurReleasePool, 看它名字, 可以理解为 当前自动释放池 ,然后有一个内存池的数组 m_pReleasePoolStack ,里面放的就是多个内存释放池了(我好像就看到一个进去了)。那么我们连上刚才的思路,进去看看push()函数,做了什么事情:

cocos2d-x内存管理(一)_第14张图片

如代码所示,push()操作new了一个自动释放池对象,并且将它赋值给 当前自动释放池(m_pCurReleasePool),然后将这个new的自动释放池对象放到CCPoolManager 里面的 释放池数组中。注意过程中对其引用计数的控制,自动释放池本身也是继承ccobject的,也有自己的引用计数,受相同的内存管理方式。

那么到这里,一个对象的autorelease()过程就完成了。


那么我来做一个简单的总结:

首先 new 一个对象, 然后执行其autorelease()方法,接下来是得到CCPoolManager 对象(这是一个全局的对象),用它的getCurReleasePool获取 当前自动释放池对象,并将这个new的对象放入 当前自动释放池对象 里面的m_pManagedObjectArray数组中,修改其被管理状态 m_bManaged 为 true。执行完这个完整的操作之后,这个新new出来的对象的引用次数为1,被管理状态为true,并且被放在一个管理对象的数组中。

先理解自动释放池的添加过程,并且搞清楚对象被添加前后之间的变化,然后下一篇,来讲被自动管理的对象是如何被引擎自动删除的。

 

你可能感兴趣的:(cocos2d-x内存管理(一))