今天要講記憶體管理的實例處理。
最近開發時遇到一個很麻煩的問題,就是在WP8上會有記憶體不足的問題。首先大家要了解,微軟在WP8手機上,有記憶體的限制(請參考這篇),512mb ram的手機只能用180mb,然而我在移植中的遊戲會跳出OutOfMemory的錯誤訊息,我就猜測是記憶體不足(畢竟我懷疑是不是有別的原因導致不足)。
首先我發現,只有進入地圖比較大的關卡才會有這問題,於是我試著縮小地圖使用的材質大小,但如果你真的去更改atlas的Format,比方說從Automatic compressed改成RGB Compressed DXT1之類的,你可以在圖片下面的註記的記憶體大小看到它微微地從4mb變成2mb(因為我是2048*2048),於是我認為這做法效果微乎其微。
於是我使用Profiler去偵測記憶體流量的變化,開啟的方式是Window>Profiler,可以點Memory來看。請一定要使用測試機來看流量,否則完全不準。
開啟後,你會看到Memory的simple選單裡面有(WP8) Commited Limit這樣的字樣,旁邊的Commited Total應該就是實際上的流量了,當你開啟後應該會看到(WP8) Commited Limit:180 B之類的字樣。
然後我發現,大小地圖載入後,Commited Total顯示的數值,並沒有太大差異,差別不到10mb,因此我判斷跟材質的格式無關,於是放棄修改地圖或圖片。
在載入小地圖時,我又發現在進入遊玩畫面前,它會突然有一個大的流量,因此,我猜測這是因為大地圖的這種超大瞬間流量過大,因此閃退。所以現在的問題就是要找出是哪個方法在負責載入,然後修改它。
後來我找到該方法後,發現它是用for迴圈去創造地圖,於是讓它在每完成一次就會停一下:
最近開發時遇到一個很麻煩的問題,就是在WP8上會有記憶體不足的問題。首先大家要了解,微軟在WP8手機上,有記憶體的限制(請參考這篇),512mb ram的手機只能用180mb,然而我在移植中的遊戲會跳出OutOfMemory的錯誤訊息,我就猜測是記憶體不足(畢竟我懷疑是不是有別的原因導致不足)。
首先我發現,只有進入地圖比較大的關卡才會有這問題,於是我試著縮小地圖使用的材質大小,但如果你真的去更改atlas的Format,比方說從Automatic compressed改成RGB Compressed DXT1之類的,你可以在圖片下面的註記的記憶體大小看到它微微地從4mb變成2mb(因為我是2048*2048),於是我認為這做法效果微乎其微。
於是我使用Profiler去偵測記憶體流量的變化,開啟的方式是Window>Profiler,可以點Memory來看。請一定要使用測試機來看流量,否則完全不準。
開啟後,你會看到Memory的simple選單裡面有(WP8) Commited Limit這樣的字樣,旁邊的Commited Total應該就是實際上的流量了,當你開啟後應該會看到(WP8) Commited Limit:180 B之類的字樣。
然後我發現,大小地圖載入後,Commited Total顯示的數值,並沒有太大差異,差別不到10mb,因此我判斷跟材質的格式無關,於是放棄修改地圖或圖片。
在載入小地圖時,我又發現在進入遊玩畫面前,它會突然有一個大的流量,因此,我猜測這是因為大地圖的這種超大瞬間流量過大,因此閃退。所以現在的問題就是要找出是哪個方法在負責載入,然後修改它。
後來我找到該方法後,發現它是用for迴圈去創造地圖,於是讓它在每完成一次就會停一下:
yield return new WaitForSeconds(0.1f);
然後將方法修改成:IEnumerator methodName ()
然後也把它的呼叫修改成:StartCoroutine(methodName());
讓它不是一口氣完成全部的地圖,而是慢慢著色。沒想到就克服這個問題了。因此各位在實作類似製造整個場景的方法時,要避免一口氣載入太多的作法,以避免瞬間流量過大,尤其是WP8平台這個問題更是明顯。
留言
張貼留言