[Android]App 内存泄漏检查工具MAT

北战南征 提交于 2019-12-01 05:13:12

Android App发生内存泄漏,常见的有Bitmap 使用后沒有recycle(),Drawable 使用后沒有setCallback(null)等。

Eclipse 有个插件工具MAT(Memory Analyzer Tool)可以帮助定位内存泄漏的对象。

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

  2. 用DDMS工具Dump出问题App的.hprof文件 比如com.world.test2.hprof Dump之前最好先运行一下GC "Cause GC" , 确保dump出来的是还不能回收的对象等。

  3. 用SDK tools下工具hprof-conv.exe 做转换 hprof-conv com.world.test2.hprof appleak.hprof

  4. 用Eclipse “Open Head Dump”打开新转换的.hprof 文件--appleak.hprof 查看图形化界面,一个一个检查怀疑的点。

总结: MAT tool不会直接告诉你哪里内存泄漏,但是会列出怀疑的对象,需要你仔细检查这些对象为什么没有被释放掉。

下面是测试code, 在Android 4.2.2上测试过。

  1. 此种情况可以引起Activity无法回收的情况,因为直接用类似private static Activity a0引用创建的Activity,导致Activity无法回收。

  2. 此种情况没有引起Activity 无法回收的情况。 按理说这种情况应该也会导致静态Drawable 锁定Activity, 引用关系mBackground1-->Button-->Activity. 待分析

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

    }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!