cocos2d-x與ios內存管理分析(在遊戲中減小內存壓力)

 


Cocos2d-x與ios內存管理分析(在遊戲中減小內存壓力)


猴子原創,歡迎轉載。轉載請註明: 轉載自Cocos2D開發網--Cocos2Dev.com,謝謝! 年ios


原文地址http://www.cocos2dev.com/?p=281緩存


注:本身之前也寫過Cocos2d-x如何優化內存的使用,以及內存不足的狀況下怎麼處理遊戲。今天在微博中看到有朋友介紹了下內存,挺詳細的。不知道是誰寫的,我記錄下。iphone


一,iOS與圖片內存


iOS上,圖片會被自動縮放到2N次方大小。好比一張1024*1025的圖片,佔用的內存與一張1024*2048的圖片是一致的。圖片佔用內存大小的計算的公式是;長**4。這樣一張512*512 佔用的內存就是 512*512*4 = 1M。其餘尺寸以此類推。(ps:IOS上支持的最大尺寸爲2048*2048)。函數


 


二,Cocos2d-x的圖片緩存


Cocos2d-x 在構造一個精靈的時候會使用spriteWithFile或者spriteWithSpriteFrameName等 不管用哪一種方式,Cocos2d-x都會將這張圖片加載到緩存中。若是是第一次加載這個圖片,那就會先將這張圖片加載到緩存,而後從緩存讀取。若是緩存中已經存在,則直接從緩存中提取,免除了加載過程。工具


 


圖片的緩存主要由如下兩個類來處理:CCSpriteFrameCache CCTextureCache測試


 


CCSpriteFrameCache加載的是一張拼接過的大圖,每個小圖只是大圖中的一個區域,這些區域信息都在plist文件中保存。用的時候只須要根據小圖的名稱就能夠加載到這個區域。優化


 


CCTextureCache 是普通的圖片緩存,咱們全部直接加載的圖片都會默認放到這個緩存中,以提升調用效率。動畫


所以,每次加載一張圖片,或者經過plist加載一張拼接圖時,都會將整張圖片加載到內存中。若是不去釋放,那就會一直佔用着。spa


 


三,渲染內存。


不要覺得,計算內存時,只計算加載到緩存中的內存就能夠了。以一張1024*1024的圖片爲例。
CCSprite *pSprite = CCSprite::spriteWithFile("a.png");
.net


 


調用上邊這行代碼之後,能夠在LEAKS工具中看到,增長了大約4M的內存。而後接着調用
addChild(pSprite);


 


這時,內存又增長了4M。也就是,一張圖片,若是須要渲染的話,那它所佔用的內存將要X2


 


再看看經過plist加載的圖片,好比這張大圖尺寸爲2048*2048。想要加載其中的一張32*32的小圖片
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("b.plist");


此時內存增長16M(汗)


CCSprite *pSpriteFrame = CCSprite::spriteWithSpriteFrameName("b1.png");
b.png
大小爲32*32,想着也就是增長一點點內存,可實際狀況是增長16M內存。也就是隻要渲染了其中的一部分,那麼整張圖片都要一塊兒被加載。


 


可是狀況不是那麼的糟糕,這些已經渲染的圖片,若是再次加載的話,內存是不會再繼續升高的,好比又增長了100b.plist的另外一個區域,圖片內存仍是共增長16+16 = 32M,而不會繼續上升。


 


四,緩存釋放


若是遊戲有不少場景,在切換場景的時候能夠把前一個場景的內存所有釋放,防止總內存太高.


CCTextureCache::sharedTextureCache()->removeAllTextures();釋放到目前爲止全部加載的圖片


CCTextureCache::sharedTextureCache()->removeUnusedTextures();將引用計數爲1的圖片釋放掉CCTextureCache::sharedTextureCache()->removeTexture(); 單獨釋放某個圖片


CCSpriteFrameCache CCTextureCache 釋放的方法差很少。


值得注意的是釋放的時機,通常在切換場景的時候釋放資源,若是從A場景切換到B場景,調用的函數順序爲B::init()---->A::exit()---->B::onEnter()


可若是使用了切換效果,好比CTransitionJumpZoom::transitionWithDuration這樣的函數,則函數的調用順序變爲B::init()---->B::onEnter()---->A::exit()


並且第二種方式會有一瞬間將兩個場景的資源疊加在一塊兒,若是不採起過分,極可能會由於內存吃緊而崩潰。


有時強制釋放所有資源時,會使某個正在執行的動畫失去引用而彈出異常,能夠調用CCActionManager::sharedManager()->removeAllActions();來解決。 


 


五,內存優化


優化的心得就是儘可能去拼接圖片,使圖片邊長儘量的保持2N次方而且裝的很滿。但要注意,有邏輯關係的圖片儘可能打包在一張大圖裏,另一點就是打包的時候要考慮到層的分佈。由於爲了渲染效率可能會用到CCSpriteBatchNode;同一個BatchNode裏的圖片都是位於一個層級的,所以必須根據各個圖片的層級關係,打包到不一樣的plist裏。有時內存和效率不能夠兼得,只能儘可能平衡了。


 


六,其餘


最後附一個各代IOS設備的內存限制狀況
設備                                             建議內存                  最大內存
iPad2/iPhone4s/iphone4                170-180mb                 512mb
iPad/iPod touch3,4/iphone3gs          40-80mb                  256mb
iPod touch1,2/iPhone3g/iPhone1         25mb                    128mb


上述建議內存只是一些人本身測試的結果,可用的RAM不大於最大內存的一半,若是程序超過最大內存的一半,則可能會掛掉。
另外在LEAKS裏查看模擬器中和真機總的內存,會有較大出入。在模擬器中的結果與實際更接近一些。

相關文章
相關標籤/搜索