内存管理——Cocos2d-x学习历程(五)

时间:2022-06-17 21:32:56

Cocos2d-x采用了引用计数与自动回收的内存管理机制。

1.每个对象包含一个用来控制生命周期的引用计数器,它就是CCObject的成员变量m_u- Reference。我们可以通过retainCount()方法获得对象当前的引用计数值。

在对象通过构造函数创建的时候,该引用值被赋为1,表示对象由创建者所引用。在其他地方需要引用对象时,我们会调用retain()方法,令其引用计数增1,表示获取该对象的引用权;在引用结束的时候调用release()方法,令其引用计数值减1,表示释放该对象的引用权。

2.另一个很有趣的方法是autorelease(),其作用是将对象放入自动回收池(CCAutore- leasePool)。当回收池自身被释放的时候,它就会对池中的所有对象执行一次release()方法,实现灵活的垃圾回收。回收池可以手动创建和释放。除此之外,引擎在每次游戏循环开始之前也会创建一个回收池,在循环结束后释放回收池。因此,即使我们没有手工创建和释放回收池,每一帧结束的时候,自动回收池中的对象也都会被执行一次release()方法。我们马上就会领略到autorelease()的方便之处。

3.虽然,Cocos2d-x已经保证每一帧结束后释放一次回收池,并在下一帧开始前创建一个新的回收池,但是我们也应该考虑到回收池本身维护着一个将要执行释放操作的对象列表,如果在一帧之内生成了大量的autorelease对象,将会导致回收池性能下降。因此,在生成autorelease对象密集的区域(通常是循环中)的前后,我们最好可以手动创建并释放一个回收池。

我们可以通过回收池管理器CCPoolManager的push()或pop()方法来创建或释放回收池,其中的CCPoolManager也是一个单例对象。

CCPoolManager::sharedPoolManager()->push();

for(int i=0; i<n; i++)

{

CCString* dataItem = CCString::createWithFormat("%d", Data[i]);

stringArray->addObject(dataItem);

}

CCPoolManager::sharedPoolManager()->pop();

这段代码包含了一个执行n次的循环,每次都会创建一个autorelease对象CCString。为了保持回收池的性能,我们在循环前使用push()方法创建了一个新的回收池,在循环结束后使用pop()方法释放刚才创建的回收池。

4.自动回收池是可嵌套的。通常,引擎维护着一个回收池,所有的autorelease对象都添加到了这个池中。多个自动回收池排列成栈结构,当我们手动创建了回收池后,回收池会压入栈的顶端,autorelease对象仅添加到顶端的池中。当顶层的回收池被弹出释放时,它内部所有的对象都会被释放一次,此后出现的autorelease对象则会添加到下一个池中。

参考理解:http://blog.163.com/zhoulong19880518@126/blog/static/60709702201210122112624/