Android 內存優化 (防Memory Leak)

Android Memory Leak 和 OOM爲什麼會發生。這次主要說說編碼層面,如何來預防Memory Leak的發生。
對象都是有生命週期的,對象的生命週期有的是進程級別的,有的是Activity所在的生命週期,隨Activity消亡;有的是Service所在的生命週期,隨Service消亡。很多情況下判斷對象是否合理存在的一個很重要的理由就是它實際的生命週期是否符合它本來的生命週期。很多Memory Leak的發生,很大程度上都是生命週期的錯配,本來在隨Activity銷燬的對象變成了進程級別的對象,Memory Leak就無法避免了。


1、常見的MemoryLeak分析

1.1 頻繁的使用static關鍵字修飾
很多初學者非常喜歡用static類static變量,聲明賦值調用都簡單方便。由於static聲明變量的生命週期其實是和APP的生命週期一樣的(進程級別)。大量的使用的話,就會佔據內存空間不釋放,積少成多也會造成內存的不斷開銷,直至掛掉。static的合理使用一般用來修飾基本數據類型或者輕量級對象,儘量避免修復集合或者大對象,常用作修飾全局配置項、工具類方法、內部類。

1.2 BitMap隱患
Bitmap的不當處理極可能造成OOM,絕大多數情況應用程序OOM都是因這個原因出現的。Bitamp位圖是Android中當之無愧的胖子,所以在操作的時候必須小心。
1.2.1 及時釋放recycle。由於Dalivk並不會主動的去回收,需要開發者在Bitmap不被使用的時候recycle掉。
1.2.2 設置一定的壓縮率。需求允許的話,應該去對BItmap進行一定的縮放,通過BitmapFactory.Options的inSampleSize屬性進行控制。如果僅僅只想獲得Bitmap的屬性,其實並不需要根據BItmap的像素去分配內存,只需在解析讀取Bmp的時候使用BitmapFactory.Options的inJustDecodeBounds屬性。
1.2.3最後建議大家在加載網絡圖片的時候,使用軟引用或者弱引用並進行本地緩存,推薦使用android-universal-imageloader或者xUtils。

1.3 頁面背景圖
在佈局和代碼中設置背景和圖片的時候,如果是純色,儘量使用color;如果是規則圖形,儘量使用shape畫圖;如果稍微複雜點,可以使用9patch圖;如果不能使用9patch的情況下,針對幾種主流分辨率的機型進行切圖。

1.4 View緩存
在ListView和GridView中,列表中的很多項(convertView)是可以重用的,不需要每次getView就重新生成一項。另外,頁面的繪製其實是很耗時的,findViewById也比較慢。所以不重用View,在有列表的時候就尤爲顯著了,經常會出現滑動很卡的現象。

1.5 引用地獄
Activity中生成的對象原則上是應該在Activity生命週期結束之後就釋放的。Activity對象本身也是,所以應該儘量避免有appliction進程級別的對象來引用Activity級別的對象,如果有的話也應該在Activity結束的時候解引用。如不應用applicationContext在Activity中獲取資源。
Service也一樣。

1.6 BroadCastReceiver、Service 解綁
綁定廣播和服務,一定要記得在不需要的時候給解綁。

1.7 handler 清理
在Activity的onDestroy方法中調用handler.removeCallbacksAndMessages(null);取消所有的消息的處理,包括待處理的消息;

1.8 Cursor及時關閉
在查詢SQLite數據庫時,會返回一個Cursor,當查詢完畢後,及時關閉,這樣就可以把查詢的結果集及時給回收掉。

1.9 I/O流
I/O流操作完畢,讀寫結束,記得關閉。

1.10 線程
線程不再需要繼續執行的時候要記得及時關閉,開啓線程數量不易過多,一般和自己機器內核數一樣最好,推薦開啓線程的時候,使用線程池。

1.11 String/StringBuffer
當有較多的字符創需要拼接的時候,推薦使用StringBuffer。


2、總結

如果以上做的都比較完美了,可以肯定你的程序會運行的非常好。
當然,有的時候我們也會爲了程序的效率性能把本來是Activity級裏才用的資源提升到進程級別,比如ImageCache,或者其它DataManager等。
我只能說,空間和時間是相對的,有的時候需要犧牲時間換取空間,有的時候需要犧牲空間換取時間。內存是空間的存在,性能是時間的存在。完美的程序是在一定條件下的完美。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章