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

    }

相关文章
相关标签/搜索