[Android]App 內存泄漏檢查工具MAT

Android App發生內存泄漏,常見的有Bitmap 使用後沒有recycle(),Drawable 使用後沒有setCallback(null)等。java

Eclipse 有個插件工具MAT(Memory Analyzer Tool)能夠幫助定位內存泄漏的對象。android

  1. 安裝MAT Update site: http://archive.eclipse.org/mat/1.1/update-site/app

  2. 用DDMS工具Dump出問題App的.hprof文件 好比com.world.test2.hprof Dump以前最好先運行一下GC "Cause GC" , 確保dump出來的是還不能回收的對象等。eclipse

  3. 用SDK tools下工具hprof-conv.exe 作轉換 hprof-conv com.world.test2.hprof appleak.hprofide

  4. 用Eclipse 「Open Head Dump」打開新轉換的.hprof 文件--appleak.hprof 查看圖形化界面,一個一個檢查懷疑的點。工具

總結: MAT tool不會直接告訴你哪裏內存泄漏,可是會列出懷疑的對象,須要你仔細檢查這些對象爲何沒有被釋放掉。測試

下面是測試code, 在Android 4.2.2上測試過。this

  1. 此種狀況能夠引發Activity沒法回收的狀況,由於直接用相似private static Activity a0引用建立的Activity,致使Activity沒法回收。插件

  2. 此種狀況沒有引發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 ;

    /*

    • Shutdown intent */ private final String INTENT_ACTION_REQUEST_SHUTDOWN = "android.intent.action.ACTION_REQUEST_SHUTDOWN";

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

    }

相關文章
相關標籤/搜索