前段時間,我們公司開發的游戲進行了第一次測試, 結果在android平臺上, 由于內存消耗過大,引起了很多崩潰的問題。 我做游戲的時候,內存過大的問題, 一直沒有引起過我的重視,現在想想,主要是沒有碰到過內存占有量太大引起崩潰的問題,那為什么這一次, 這個問題這么的突出呢, 因為這一次我們的游戲類型是一款掛機游戲,也就是戰斗部分,是永遠存在的。問題就來了,戰斗中會有大量的怪物,技能特效,都加載內存中,而切換界面的時候,戰斗是沒有釋放的,之前的游戲,當切換到非戰斗界面,戰斗就會被釋放,自然不會有很大的內存問題,其實出現這個問題,也是有好處的,至少讓我更加重視內存消耗了。 既然出現了這個問題,那么接下來就是如何解決。 1 場景切換的時候,調用引擎函數removeUnusedTextures() 來釋放那些引用計數為1的圖片緩存資源,雖然說緩存是為了性能更快,但是當為了追求性能而引起別的問題,那么將是得不償失。 2 使用了上面的方法后,發現在一些低端機,還是會出現內存不足,那么需要進一步優化。 3 我們ui工程用的是cocostudio制作的,當時每個界面對應著一張大圖,跟蹤引擎代碼,發現引擎加載大圖的時候,首先會把這張大圖放到系統的紋理緩存內,和普通的小圖一樣。所以,每一張texturePacker打包出來的大圖,在引擎的紋理緩存內都對應著一份緩存,而我們的打包出來的大圖,一般都是比較大的資源,所以可以清楚這部分數據。接著引擎會遍歷該大圖內所有的小圖,生成精靈幀,存放到精靈幀緩存內,在這里看到,注意到,加載一個一個的精靈幀的時候,也會有同名的處理, 也就是說,如果兩張大圖內包含相同名字的小圖,那么只認最開始加載的那個小圖,后面發現同名,會直接跳過。在這里,又發現了一個優化點,就是當釋放了某個界面的時候,也可以刪除該界面對應的精靈幀,當我想這么做的時候,卻發現了一個問題,當時美術拼圖的時候,最開始設計的是,每一個界面自己用一張自己的大圖,外加一張公共用到的大圖(該大圖包含,所有公用的資源)后來,為了方便,也是自己經驗不夠,美術就沒按照這個規則了,一張ui工程,用了自己的,也用了不是公用的大圖,這樣就導致優化的時候,不好釋放精靈幀資源,以后這些細節還是很需要注意才行。還有一個問題,就是只要是在代碼里面會有動態的加載圖片的資源(不是加載cocostudio文件一次性加載的 通俗的講 就是非靜態圖片) 那么務必用小圖,不用大圖,如果用了大圖,將導致該大圖不能被刪除。 所以,以后我自己開發項目的時候, 是不允許出現 代碼里面加載圖片用 cocostudio里面的大圖的。 現在想想,如果遵守了這幾個規則,那么在我們各個界面的onexit() 函數內,釋放掉他自己對應的大圖,和大圖內對應的精靈幀,那么也能節約不少內存,這個是結合cocostudio texturePacker texturecach sPRiteFrameCach 一起來講的,也是我自己總結的。 上面說的是從 代碼層面優化內存,還有幾十從資源本身也可以做一些優化,但是有一點一直沒有搞懂,就是網絡上說什么圖片格式不要用rgba8888的,要用什么rgba4444啥的,只知道大的背景圖因為一般無需透明度,可以直接用jpg格式,而jpg格式其實是rgb888格式的, 給我的感覺是每個像素只占24個字節,但是當打印緩存內的jpg格式的大圖的時候,發現他的格式一樣的是每個像素占了32位,這我就搞不懂了。 還有什么rgba4444啥的,不知道是不是美術直接設置成這個格式,還是不是需要程序內再一次設置,沒搞懂。 在這一點上,引擎文檔也沒有任何的說明。先記錄到這。。。 接上,上次說到圖片資源像素格式的問題,今天又針對性的跟蹤了一下代碼。 如果是png類型的圖片,無論美術導出的是什么格式, 引擎在初始化image的時候,都會轉換成 i8 ai88 rgb888 rgba8888 四種類型中的一種,也就是說 即便導出的是rgba4444 實際上會給image設置為rgba8888的格式,接著在初始化texture的時候, 會有一個convertDataToFormat步驟,會把當前image的格式轉換成引擎默認用的像素format g_defaultAlphaPixelFormat 而 g_defaultAlphaPixelFormat默認設置的是rgba8888格式,所以我測試用一張 rgba4444 的圖片 結果內存每個像素也是占32位。但是當發現如果用的是pvr格式的圖片,如果用的是rgba4444格式,觀察在內存中每個像素就只占16位,這就對了,因為引擎不會把rgba4444的轉換為系統默認的格式,轉換的時候,只對以上四種格式。 說的不清楚,我自己總結一下,引擎默認用的格式是rgba8888 32位像素格式,如果不改變,那么所有的png圖片 在內存中都將會是每個像素占32位,當然如果改變默認的像素格式,那么占的內存也會對應的改變,而pvr格式的圖片,如果設置成了rgba4444 他在內存就是每個像素16,有內存上的變小。 感覺說的不是很清楚,但是應該算是徹底懂了。
新聞熱點
疑難解答