android內存溢出

內存溢出主要由以下幾種情況引起:

1.數據庫的cursor沒有關閉。

2.構造adapter沒有使用緩存contentview。

3.調用registerReceiver後未調用unregisterReceiver()。

4.未關閉InputStream/OutputStream。

5.Bitmap使用後未調用recycle()。

6.Context泄漏。

前5種情況容易發現和解決,只要把該關的及時關閉,該調用的方法及時調用,就不會有太多問題,另外java裏還有軟引用幫助管理內存:

SoftReference<Bitmap> bitmap;
bitmap = new SoftReference<Bitmap>(pBitmap);
if(bitmap != null){

if(bitmap.get() != null && !bitmap.get().isRecycled()){
bitmap.get().recycle();
bitmap = null;
}
}

下面着重介紹Context泄漏。

這是一個很隱晦的內存泄露的情況。先看一個Android官網提供的例子:

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);
}

這段代碼效率很快,但同時又是極其錯誤的;在第一次屏幕方向切換時它泄露了一開始創建的Activity。當一個Drawable附加到一個View上時,View會將其作爲一個callback設定到Drawable上。上述的代碼片段,意味着Drawable擁有一個TextView的引用,而TextView又擁有Activity(Context類型)的引用,換句話說,Drawable擁有了更多的對象引用。即使Activity被銷燬,內存仍然不會被釋放。

另外,對Context的引用超過它本身的生命週期,也會導致Context泄漏。所以儘量使用Application這種Context類型。這種Context擁有和應用程序一樣長的生命週期,並且不依賴Activity的生命週期。如果你打算保存一個長時間的對象,並且其需要一個Context,記得使用Application對象。你可以通過調用Context.getApplicationContext()或Activity.getApplication()輕鬆得到Application對象。

最近遇到一種情況引起了Context泄漏,就是在Activity銷燬時,裏面有其他線程沒有停。

總結一下避免Context泄漏應該注意的問題:

1.使用Application這種Context類型。

2.注意對Context的引用不要超過它本身的生命週期。

3.慎重的使用“static”關鍵字。

4.Context裏如果有線程,一定要在onDestroy()裏及時停掉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章