Android內存泄漏雜談

內存泄漏:是指內存得不到GC的及時回收,從而形成內存佔用過多。從而致使程序Crash,也就是常說的OOM。java


1、static
先來看如下一段代碼markdown

public class DBHelper {

    private static DBHelper db= null;

    private DBHelper() {

    }

    public static DBHelper getInstance(Context context) {
        if (bitmapUtils == null) {
            synchronized (DBHelper.class) {
                if (db== null) {
                    db= new db(context,DBNAME);

                }
            }
        }
        return db;
    }
}

這種代碼在項目中非常常見。假設你們細緻一點。應該能發現問題在那裏。異步

helper中持有了context的應用。而DBHelper是全局的,也就是說,當在一個Activity中使用了DBHelper,即便這個Activity退出了,這個Activity也無法被GC回收。從而形成Activity一直駐留在內存中。ide


這個解決方式也比較簡單,代碼例如如下post

public class DBHelper {

    private static DBHelper db= null;

    private DBHelper() {

    }

    public static DBHelper getInstance(Context context) {
        if (bitmapUtils == null) {
            synchronized (DBHelper.class) {
                if (db== null) {
                    db= new db(context.getApplicationContext(),DBNAME);

                }
            }
        }
        return db;
    }
}

僅僅需要把context改爲ApplicationContext()便可,因爲ApplicationContext自己就是全局的。spa


2、非靜態內部類、Handler
先來看一段代碼code

private Handler handler = new Handler(){
        @Override
        public void dispatchMessage(Message msg) {
            // 消息處理
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Thread(new Runnable() {

            @Override
            public void run() {
                // 耗時操做
                handler.sendEmptyMessage(1);
            }
        }).start();
    }

咱們知道非靜態內部類會持有外部類的引用,此時這裏的Handler持有着外部Activity的引用,當咱們在Activity的內部類中進行異步耗時操做時,咱們的Activity假設此時被finish掉了,而異步任務沒有運行結束,這就會致使咱們的Activity對象不能及時的被GC回收,從而致使內存問題。對象


這種問題解決起來也很是easy生命週期

  • 不要在匿名內部類中進行異步操做
  • 使用靜態匿名內部類 總結:內存問題大多數都是因爲對對象生命週期的不巧當處理形成的。在使用某個對象時。咱們需要細緻研究對象的生命週期。當處理一些佔用內存較大並且生命週期較長的對象時。應用使用軟引用對其便可處理。及時關閉不使用的資源。
相關文章
相關標籤/搜索