out momory 一陣天旋地轉內存又溢出了。在手機上這種痛苦經常都有,套一句俗話在手機上用內存必須勒緊褲腰帶。雖然現在pc內存上G都不奇怪,可是在手機上卻只能以K來記,可能某位同志會馬上跳出來說也有上M的,記住中國還不富大多數手機都是低端手機。寫手機程序讓我仿佛回到了dos時代(自我安慰一下那個時代也煉出了不少高手說不定我是下一個)。言歸正傳做內存優化可以歸結為以下幾種方法。代碼優化,圖片優化,第三方工具優化等…
一.代碼優化 內存會溢出肯定和代碼逃不了關系,99.99%學java的人都知道垃圾回收器是java的一大優點并據此來嘲笑C++。顯然這個特性為代碼編寫者省了不少事,但這個特性卻帶來了不少隱患。舉個例子在游戲當中經常有不同場景的切換,如從游戲邏輯退到主菜單邏輯,對游戲邏輯對象的態度很多人會選擇忘記等待垃圾回收器來收尸^_^。乍看之下似乎并無不妥垃圾回收器會來善后。實際上垃圾回收器并非實時的,它不像C++的Delete語句馬上釋放不用的內存。當從游戲邏輯切換到主菜單邏輯這時兩個對象同時存在很可能這時內存就不夠用了。讀到這里很多人會發現實際上垃圾回收器在j2me上并不怎么好用,從一個角度上來講在j2me上所有垃圾必須由手工釋放,除簡單類型以外所有對象都必須顯式地置空例如 imgs=null; 實際上java提供了一個不錯的工具用來查找內存溢出,java.lang.Runtime.freeMemory() 。它可以返回當前的剩余內存數,將它適當的安放在代碼中可以有效的監測內存使用狀況。很大一部份的j2me程序員之前都是從事pc軟件開發工作,充裕的內存掩蓋了許多寫代碼的不良習慣。如下所示: //a 不為空 a=new Logic(); 很多人可能對此有異議,他們會認為新的對象會把舊的對象沖掉并且釋放內存。這里面包含兩個問題:1. 該段代碼是先創建對象然后再進行賦值操作的,也就是說在這期間有兩個對象同時存在這就很可能會產生溢出。2. 這樣做也會妨礙垃圾回收器的工作 較好的寫法如下: a=null; a=new Logic(); 雖然麻煩了點但在j2me中還是必要的。接著看下例。 drawString("游戲時間:" + time ,50,50,Graphics.LEFTGraphics.TOP); "游戲時間:" + time 很完美在paint()方法當中每次都被刷一遍顯示在屏幕上。危機往往隱藏在美麗的外表,該語句會引起新的內存重新分配來存儲 "游戲時間:" + time 而顯示完以后又必須由垃圾回收器釋放,用了雙倍時間,并且容易發生內存溢出。依此類推在重復執行的方法里應盡量避免重復定義對象。與paint()方法類似在循環里也有類似的情況存在。 把所有對象的初始化放在構造函數里想必是再正當不過了,大多數人通常的做法是把當前邏輯所要用到的資源通通初始化完畢。 很大一部份的內存溢出都是發生在構造函數中。內存使用的高峰期都是在構造函數中所以避開這個高峰能有效的防止溢出。建議最好的辦法是第一次使用時初始化。如下所示 if (img==null){ //初始化 } 現在做游戲很多時候都需要地圖數組,聲音數組,還有一些其它資源這些資源很多可以放在代碼中也有的可以放在文件當中。 強烈建議將這些資源放在文件中需要時在load進來。這些資源文件如果放在代碼中則會占用不小的代碼段空間,而代碼一般是程序一運行就裝載到內存當中。 除上面列舉的方法外還有一些大家所熟知的順便一提, 比如關閉沒用的rms ,關閉沒用的網絡連接,關閉沒用的流。正確地停止線程。良好的程序架構減少代碼偶合性也是一個不錯的方法,無論在代碼調式,內存釋放都可以做到非常清析。