咱們如今就來總結一下可能致使內存泄露的狀況: html
在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(), 保證其必定會被調用 }
在調用registerReceiver後,若未調用unregisterReceiver,其所佔的內存是至關大的。
而咱們常常能夠看到相似於以下的代碼: 數據庫
registerReceiver(new BroadcastReceiver() { ... }, filter); ...這是個很嚴重的錯誤,由於它會致使BroadcastReceiver不會被unregister而致使內存泄露。
未關閉InputStream/OutputStream 網絡
在使用文件或者訪問網絡資源時,使用了InputStream/OutputStream也會致使內存泄露 app
根據SDK的描述,調用recycle並非必須的。但在實際使用時,Bitmap佔用的內存是很大的,因此當咱們再也不使用時,儘可能調用recycle()以釋放資源。 ide
這是一個很隱晦的內存泄露的狀況。
先讓咱們看一下如下代碼: 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在銷燬後,內存不會被釋放。