題目:請簡單說一下你在android開發過程中如何對記憶體進行最佳化。
分析:眾所周知,Android應用程式是運行在java虛擬機器之中,記憶體回收採用的是java當中的GC機制,由系統進行整體調度,開發人員無法直接幹預,因此在開發過程中對記憶體的合理使用就顯得尤其重要。
1.對Bitmap的最佳化:
在Android應用中,最消耗記憶體的就是Bitmap的圖片資源。而在adnroid系統中,讀取Bitmap時,分配給虛擬機器中堆棧的大小隻有8M,如果超出了,就會OOM(Out Of Memory)。
a>要及時回收Bitmap,當Bitmap使用完畢後,執行如下代碼:
if(bitmap && !bitmap.isRecycle()){ bitmap.recycle(); bitmap = null;}system.gc();
注意,最後一句system.gc();只是請求系統儘快進行記憶體回收,而不能保證系統立即做出反應。
由於產生Bitmap對象是通過調用JNI介面實現的,釋放同樣也需要調用JNI介面。所以載入Bitmap對象到記憶體之後是包含兩部分地區的,一個是java的部分,一個是C的部分。系統的GC機制在回收的時候只能回收java部分的記憶體,而不能釋放C部分的記憶體,C部分的記憶體只能通過調用recycle()介面來釋放。
那若不調用recycle()介面,是否就一定存在記憶體流失呢?也不是。當應用的進程被應用自己或者被系統殺死後,整個進程的記憶體就會被釋放,當然也包含C的部分。
b>捕獲異常
Bitmap bitmap = null;try{ bitmap = BitmapFactory.decodeFile(path);}catch(OutOfMemoryError e){ // do something}if(!bitmap) return default_bitmap;
這樣,在發生OOM的時候,應用就不會崩潰,而是會顯示一張預設的圖片。注意在catch的地方catch的是Error,而不是Exception。
c>緩衝通用的Bitmap對象
對於那種在應用中要多次重複用到的圖片,可以在記憶體中只保留一個副本,即可以定義成全域變數或者靜態變數。
d>壓縮圖片
2.使用軟引用和弱引用
Java將對象的引用分為四種層級,從而使程式能夠更靈活的控制對象的生命週期。四種層級從高到低分別是:強引用,軟引用,弱引用,虛引用。
a>強引用就是通常的用法,不再贅述。
b>軟引用,如果一個對象只有軟引用,那麼當記憶體足夠的時候,它和強引用的對象沒區別;當記憶體不足時,系統會將它回收掉。
private Map<String , SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>;public void addBmToCache(String path){ Bitmap bm = BitmapFactory.decodeFile(path); SoftReference<Bitmap> softbm = new SoftReference<Bitmap>(bm); imageCache.put(path, softbm);}public Bitmap getBmByPath(String path){ SoftReference<Bitmap> softbm = imageCache.get(path); if(softbm == null) return null; Bitmap bm = softbn.get(); return bm;}
c>弱引用,如果一個對象只有弱引用,那麼在GC線程掃描過程中,一旦發現此類對象,無論記憶體是否足夠,這個對象都將被回收。
軟引用和弱引用的區別在於,弱引用的生命週期更短,隨時有可能被回收;軟引用只有在記憶體不足的時候才會被回收。
d>虛引用,形同虛設,主要是用來跟蹤記憶體回收情況,必須和引用隊列聯合進行使用。
由於筆者水平有限,給各面試題提供的思路或代碼難免會有錯誤,還請讀者批評指正。另外,熱忱歡迎讀者能夠提供更多、更好的面試題,本人將感激不盡。如有任何意見或建議,歡迎在評論中告知。
博主徐方磊對本部落格文章享有著作權。網路轉載請註明出處http://blog.csdn.net/shishengshi。整理出版物請和作者聯絡。