Android下常見的內存泄露


咱們如今就來總結一下可能致使內存泄露的狀況: html

  1. 查詢數據庫而沒有關閉Cursor

    在Android中,Cursor是很經常使用的一個對象,但在寫代碼是,常常會有人忘記調用close, 或者由於代碼邏輯問題情況致使close未被調用。
    一般,在Activity中,咱們能夠調用startManagingCursor或直接使用managedQuery讓Activity自動管理Cursor對象。
    但須要注意的是,當Activity介紹後,Cursor將再也不可用!
    若操做Cursor的代碼和UI不一樣步(如後臺線程),那沒須要先判斷Activity是否已經結束,或者在調用OnDestroy前,先等待後臺線程結束。

    除此以外,如下也是比較常見的Cursor不會被關閉的狀況
    java

    try {  
            Cursor c = queryCursor();  
            int a = c.getInt(1);  
            ......  
            c.close();  
        } catch (Exception e) {  
        }
    雖然表面看起來,Cursor.close()已經被調用,但若出現異常,將會跳過close(),從而致使內存泄露。

    因此,咱們的代碼應該以以下的方式編寫: android


    Cursor c = queryCursor();  
        try {      
            int a = c.getInt(1);  
            ......  
        } catch (Exception e) {  
        } finally {  
            c.close(); //在finally中調用close(), 保證其必定會被調用   
        }


  2. 調用registerReceiver後未調用unregisterReceiver().

    在調用registerReceiver後,若未調用unregisterReceiver,其所佔的內存是至關大的。
    而咱們常常能夠看到相似於以下的代碼: 數據庫

    registerReceiver(new BroadcastReceiver() {  
            ...  
        }, filter); ...
    這是個很嚴重的錯誤,由於它會致使BroadcastReceiver不會被unregister而致使內存泄露。


  3. 未關閉InputStream/OutputStream 網絡

    在使用文件或者訪問網絡資源時,使用了InputStream/OutputStream也會致使內存泄露 app


  4. Bitmap使用後未調用recycle()

    根據SDK的描述,調用recycle並非必須的。但在實際使用時,Bitmap佔用的內存是很大的,因此當咱們再也不使用時,儘可能調用recycle()以釋放資源。 ide


  5. Context泄露

    這是一個很隱晦的內存泄露的狀況。
    先讓咱們看一下如下代碼: this

    private static Drawable sBackground;  
          
        @Override  
        protected void onCreate(Bundle state) {  
          super.onCreate(state);  
            
          TextView label = new TextView(this);  
          label.setText("Leaks are bad");  
            
          if (sBackground == null) {  
            sBackground = getDrawable(R.drawable.large_bitmap);  
          }  
          label.setBackgroundDrawable(sBackground);  
            
          setContentView(label);  
        }
    在這段代碼中,咱們使用了一個static的Drawable對象。 這一般發生在咱們須要常常調用一個Drawable,而其加載又比較耗時,不但願每次加載Activity都去建立這個Drawable的狀況。 此時,使用static無疑是最快的代碼編寫方式,可是其也很是的糟糕。 當一個Drawable被附加到View時,這個View會被設置爲這個Drawable的callback (經過調用Drawable.setCallback()實現)。 這就意味着,這個Drawable擁有一個TextView的引用,而TextView又擁有一個Activity的引用。 這就會致使Activity在銷燬後,內存不會被釋放。
相關文章
相關標籤/搜索