1. 程式人生 > >android防記憶體洩漏與記憶體優化的方法整理

android防記憶體洩漏與記憶體優化的方法整理

記憶體洩漏

一、單利洩漏

存在記憶體洩露問題的一些程式碼片段像下面這樣:

 public class Util {  

           private Context mContext;  

           private static Util sInstance;  

           private Util(Context context) {  

               this.mContext = context;  

         }  

        public static Util getInstance(Context context) {  

            if (sInstance == null) {  

              sInstance = new Util(context);  

            }  

           return sInstance;  

     }  

}

假設Activity  A 裡使用Util類:

Util.getInstance(this); 

程式碼大意就是這樣,這樣寫的問題就是,在Activity A 裡使用Util類,傳入的context 是 actvitiy-context。試想一下,當Activity A 生命週期結束,但Util類裡面卻還存在A的引用 (mContext),這樣Activity A佔用的記憶體就一直不能回收,而A的物件也不會再被使用。本人寫程式碼測試過,在A中呼叫了finish(),A的destroy()方法也被執行了,但其佔用的記憶體,比如說,ImageView佔用的記憶體,還是不能釋放的。

那麼如何解決這個問題呢?在A中,可以用Util.getInstance(getApplicationContext());或Util.getInstance(getApplication()); 代替。 

因為Application的生命週期是貫穿整個程式的,所以Util類持有它的引用,也不會造成記憶體洩露問題。

 

 

2、資源使用完未關閉

一、動態註冊廣播,一定要在onDestroy  呼叫unregisterReceiver 取消註冊,不然當activity結束後,廣播不被回收,導致記憶體洩漏。

二、io Cursor 流要記得close,一定要在finally去close 防止拋異常沒執行close 。

三、bitmap 使用時要記錄recycle,不注意,很容易出現ANR。

 

3、Handler造成記憶體洩露,

          方法一:通過程式邏輯來進行保護。
          1.在關閉Activity的時候停掉你的後臺執行緒。執行緒停掉了,就相當於切斷了Handler和外部連線的線,Activity自然會在合適的時候被回收。 
          2.如果你的Handler是被delay的Message持有了引用,那麼使用相應的Handler的removeCallbacks()方法,把訊息物件從訊息佇列移除就行了。

            方法二:將Handler宣告為靜態類。

4、AsyncTask記憶體洩露

         在銷燬當前Activity的時候手動去呼叫AsyncTask的cancle方法,(activity 結束後,AsyncTask會在doInBackground()方法執行完畢之後再結束)

 

記憶體優化

1、儘量使用StringBuilder,不要用"+"去拼接字串,浪費不必要的記憶體。

2、圖片能壓縮,儘量壓縮。

3、儘量使用池:執行緒池,快取池,okhttp裡面的connectionPool(Socket複用池),okio SegmentPool(buffer複用池)------(可以重複        使用物件,減少記憶體開銷,記憶體拉動,cpu開銷)

4、常用的資料結構優化:  能用SparseArray就不用HashMap.

5、xml層級和view :xml層級最好控制在5層以內,多用ViewStub ,include,merge。