cocos2dx的内存管理方式

                                   cocos2dx的内存管理方式

cocos是通过引用计数方式管理内存,主要通过两种方式实现


1.手动管理内存

当我们创建一个实例时,基类Ref里面有一个叫referenceCount的参数就会置1,它代表我们引用的次数,使用retain()函数

可以使refernceCount+1,release()函数会使referenceCount-1,当这个参数减至0时会被引擎delete掉释放内存

cocos2dx的内存管理方式

 

2.自动回收池 

有手动就会有自动。我们在create()一个对象时,调用new函数创建对象并且还会利用autorelease()方法把该对象的指针加入自动回收池,主线程每一帧在Application::getInstance()->run()的过程中会调用 mainloop()方法

cocos2dx的内存管理方式

mainloop()方法中会利用单例的PoolManager类getCurPool()获取当前的自动回收池,并调用自动回收池中的clear()方法,

cocos2dx的内存管理方式

clear()方法里,会遍历移除所有与该自动回收池相关联的对象,并调用一次release()方法,如果这个对象没被调用且referenceCount被减至0就会被delete掉。若这个对象已经addChild到其他控件上呗引用的话,则referenceCount不为0,等其父节点被清理时再回收

cocos2dx的内存管理方式

 

好处:

1.无需手动的release()和retain(),避免内存泄漏。

2.在每一帧结束后对无用的对象进行自动处理内存回收,方便可靠。

 

可优化的地方:

1.我们的PoolManager管理的是一个_releasePoolStack(存储自动回收池的栈),一般情况下,每一帧结束后我们只是把当前的池子给清空,然后执行下一帧的操作。但是我们也应该考虑到释放池本身维护着一个将要执行释放操作的对象列表,如果在一帧之内生成了大量的autorelease对象,将会导致释放池性能下降。因此,在生成autorelease对象密集的区域(通常是循环中)的前后,我们最好可以手动创建并释放一个回收池。

2.autorelease()只有在自动释放池被释放时才会进行一次释放操作,如果对象释放的次数超过了应有的次数,则这个错误在调用autorelease()时并不会被发现,只有当自动释放池被释放时(通常也就是游戏的每一帧结束时),游戏才会崩溃。在这种情况下,定位错误就变得十分困难了。因此,我们建议在开发过程中应该避免滥用autorelease(),只在工厂方法等不得不用的情况下使用,尽量以release()来释放对象引用。