android 記憶體最佳化一

來源:互聯網
上載者:User

標籤:

常見記憶體泄露原因

 

Context對象泄漏

1、如果一個類持有Context對象的強引用,就需要檢查其生存周期是否比Context對象更長。否則就可能發生Context泄漏。

2、View持有其建立所在Context對象的引用,如果將View對象傳遞給其它生存周期比View所在Context更長的強引用,就可能會引起記憶體流失。

例如View#setTag(int, Object)的記憶體流失https://code.google.com/p/android/issues/detail?id=18273

3、把Context對象賦給static變數。

 

 

避免Context對象泄漏Checklist

1、檢查所有持有對Context對象強引用的對象的生命週期是否超出其所持有的Context對象的生命週期。

2、檢查有沒有把View傳出到View所在Context之外的地方,如果有的話就需要檢查生命週期。

3、工具類中最好不要有Context成員變數,盡量在調用函數時直接通過調用參數傳入。如果必須有Context成員變數時,可以考慮使用WeakReference來引用Context對象。

4、View持有其建立所在Context對象的引用,如果將View對象傳遞給其它生存周期比View所在Context更長的強引用,就可能會引起記憶體流失。

5、 檢查把Context或者View對象賦給static變數的地方,看是否有Context泄漏。

6、檢查所有把View放入容器類的地方(特別是static容器類),看是否有記憶體流失。7、使用WeakHashMap也需要注意有沒有value-key的引用。

7、盡量使用ApplicationContext。

 

Handler對象泄漏

 

1、發送到Handler的Message實際上是加入到了主線程的訊息佇列等待處理,每一個Message持有其目標Handler的強引用。

如我們通常使用的匿名內部類Handler

HandlermHandler = new Handler() {    @Override    public voidhandleMessage(Message msg) {       mImageView.setImageBitmap(mBitmap);    }}

上面是一段簡單的Handler的使用。當使用內部類(包括匿名類)來建立Handler的時候,Handler對象會隱式地持有一個外部類對象 (通常是一個Activity)的引用,因為View會依附著一個Activity。而Handler通常會伴隨著一個耗時的後台線程(例如從網路拉取圖 片)一起出現,這個後台線程在任務執行完畢(例片下載完 畢)之後,通過訊息機制通知Handler,然後Handler把圖片更新到介面。然而,如果使用者在網路請求過程中關閉了Activity,正常情況 下,Activity不再被使用,它就有可能在GC檢查時被回收掉,但由於這時線程尚未執行完,而該線程持有Handler的引用(不然它怎麼發訊息給 Handler?),這個Handler又持有Activity的引用,就導致該Activity無法被回收(即記憶體泄露),直到網路請求結束(例片 下載完畢)。另外,如果你執行了Handler的postDelayed()方法,該方法會將你的Handler裝入一個Message,並把這條 Message推到MessageQueue中,那麼在你設定的delay到達之前,會有一條MessageQueue -> Message -> Handler -> Activity的鏈,導致你的Activity被持有引用而無法被回收。

當然,應為是Handler對外部持有引用的原因,我們就可以將Activity設定為一個弱引用,在不必要的時候,不再執行內部方法。

import android.app.Activity;importandroid.content.Context;importandroid.os.Handler;importandroid.os.Message;  importjava.lang.ref.WeakReference;  publicclass WeakRefHandler extends Handler{    WeakReference<context> mWeakContext;      public WeakRefHandler(Context context)    {        mWeakContext = newWeakReference<context>(context);    }      @Override    public void handleMessage(Message msg)    {        if((mWeakContext.get() instanceofActivity )&& ((Activity)mWeakContext.get()).isFinishing())                return ;        if(mWeakContext==null){            return ;        }        super.handleMessage(msg);    }}

 

android 記憶體最佳化一

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.