Android App發生內存泄漏,常見的有Bitmap 使用後沒有recycle(),Drawable 使用後沒有setCallback(null)等。java
Eclipse 有個插件工具MAT(Memory Analyzer Tool)能夠幫助定位內存泄漏的對象。android
安裝MAT Update site: http://archive.eclipse.org/mat/1.1/update-site/app
用DDMS工具Dump出問題App的.hprof文件 好比com.world.test2.hprof Dump以前最好先運行一下GC "Cause GC" , 確保dump出來的是還不能回收的對象等。eclipse
用SDK tools下工具hprof-conv.exe 作轉換 hprof-conv com.world.test2.hprof appleak.hprofide
用Eclipse 「Open Head Dump」打開新轉換的.hprof 文件--appleak.hprof 查看圖形化界面,一個一個檢查懷疑的點。工具
總結: MAT tool不會直接告訴你哪裏內存泄漏,可是會列出懷疑的對象,須要你仔細檢查這些對象爲何沒有被釋放掉。測試
下面是測試code, 在Android 4.2.2上測試過。this
此種狀況能夠引發Activity沒法回收的狀況,由於直接用相似private static Activity a0引用建立的Activity,致使Activity沒法回收。插件
此種狀況沒有引發Activity 沒法回收的狀況。 按理說這種狀況應該也會致使靜態Drawable 鎖定Activity, 引用關係mBackground1-->Button-->Activity. 待分析code
<!-- lang: java -->
public class MainActivity extends Activity implements Button.OnClickListener{
final private static String TAG = "MainActivity";
private static Drawable mBackground1; private static Drawable mBackground2; private static Drawable mBackground3; private static Drawable mBackground4;
private static Activity a0 ; private static Activity a1 ; private static Activity a2 ; private static Activity a3 ; private static Activity a4 ;
/*
@Override public void onCreate(Bundle savedInstanceState) { Log.v(TAG, "onCreate Activity="+this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
//1 if(false){ if(a0 == null){ a0 = this; Log.v(TAG, "onCreate Activity a0="+a0); } else if(a1 == null){ a1 = this; Log.v(TAG, "onCreate Activity a1="+a1); } else if(a2 == null){ a2 = this; Log.v(TAG, "onCreate Activity a2="+a2); } else if(a3 == null){ a3 = this; Log.v(TAG, "onCreate Activity a3="+a3); } else if(a4 == null){ a4 = this; Log.v(TAG, "onCreate Activity a4="+a4); } } //set up button listener Button myButton = (Button)findViewById(R.id.button_poweroff); myButton.setOnClickListener(this); myButton = (Button)findViewById(R.id.button_reboot); myButton.setOnClickListener(this); //2 if (mBackground1 == null) { Log.v(TAG, "onCreate mBackground1"); mBackground1 = getResources().getDrawable(R.drawable.adbroot_004); myButton.setBackgroundDrawable(mBackground1); } else if(mBackground2 == null){ Log.v(TAG, "onCreate mBackground2"); mBackground2 = getResources().getDrawable(R.drawable.test002); myButton.setBackgroundDrawable(mBackground2); } else if(mBackground3 == null){ Log.v(TAG, "onCreate mBackground3"); mBackground3 = getResources().getDrawable(R.drawable.test003); myButton.setBackgroundDrawable(mBackground3); } else if(mBackground4 == null){ Log.v(TAG, "onCreate mBackground4"); mBackground4 = getResources().getDrawable(R.drawable.adbroot_003); myButton.setBackgroundDrawable(mBackground4); }
}