天天看點

cocos2dx的記憶體管理方式                                   cocos2dx的記憶體管理方式

                                   cocos2dx的記憶體管理方式

cocos是通過引用計數方式管理記憶體,主要通過兩種方式實作

1.手動管理記憶體

當我們建立一個執行個體時,基類Ref裡面有一個叫referenceCount的參數就會置1,它代表我們引用的次數,使用retain()函數

可以使refernceCount+1,release()函數會使referenceCount-1,當這個參數減至0時會被引擎delete掉釋放記憶體

cocos2dx的記憶體管理方式                                   cocos2dx的記憶體管理方式

2.自動回收池 

有手動就會有自動。我們在create()一個對象時,調用new函數建立對象并且還會利用autorelease()方法把該對象的指針加入自動回收池,主線程每一幀在Application::getInstance()->run()的過程中會調用 mainloop()方法

cocos2dx的記憶體管理方式                                   cocos2dx的記憶體管理方式

在mainloop()方法中會利用單例的PoolManager類getCurPool()擷取目前的自動回收池,并調用自動回收池中的clear()方法,

cocos2dx的記憶體管理方式                                   cocos2dx的記憶體管理方式

clear()方法裡,會周遊移除所有與該自動回收池相關聯的對象,并調用一次release()方法,如果這個對象沒被調用且referenceCount被減至0就會被delete掉。若這個對象已經addChild到其他控件上呗引用的話,則referenceCount不為0,等其父節點被清理時再回收

cocos2dx的記憶體管理方式                                   cocos2dx的記憶體管理方式

好處:

1.無需手動的release()和retain(),避免記憶體洩漏。

2.在每一幀結束後對無用的對象進行自動處理記憶體回收,友善可靠。

可優化的地方:

1.我們的PoolManager管理的是一個_releasePoolStack(存儲自動回收池的棧),一般情況下,每一幀結束後我們隻是把目前的池子給清空,然後執行下一幀的操作。但是我們也應該考慮到釋放池本身維護着一個将要執行釋放操作的對象清單,如果在一幀之内生成了大量的autorelease對象,将會導緻釋放池性能下降。是以,在生成autorelease對象密集的區域(通常是循環中)的前後,我們最好可以手動建立并釋放一個回收池。

2.autorelease()隻有在自動釋放池被釋放時才會進行一次釋放操作,如果對象釋放的次數超過了應有的次數,則這個錯誤在調用autorelease()時并不會被發現,隻有當自動釋放池被釋放時(通常也就是遊戲的每一幀結束時),遊戲才會崩潰。在這種情況下,定位錯誤就變得十分困難了。是以,我們建議在開發過程中應該避免濫用autorelease(),隻在工廠方法等不得不用的情況下使用,盡量以release()來釋放對象引用。

繼續閱讀