本文结合《Android开发艺术探索》书籍中的内存分析例子来讲解如何利用MAT工具来查找内存泄漏(以AndroidStudio开发工具为例)。
1、下载MAT(Eclipse Memory Analyzer)工具,windows64位网盘下载地址:http://pan.baidu.com/s/1pLlbOBD,或者通过官网下载:https://www.eclipse.org/mat/downloads.php,下载完毕后解压即可,目录结构如下:
2、模拟内存泄漏的场景,源码如下,启动退出三次app即可。
代码结构如下
MainActivity.java
package androidstudy.androidartstudy05; import android.content.Context;import android.os.Bundle;import android.os.SystemClock;import android.support.v7.app.AppCompatActivity;import android.util.Log; import androidstudy.androidartstudy05.manager.TestManager; public class MainActivity extends AppCompatActivity implements TestManager.OnDataArrivedListener { private static final String TAG = "MainActivity"; private static Context sContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sContext = this; TestManager.getInstance().registerListener(this); } private synchronized void testANR() { SystemClock.sleep(30 * 1000); } private synchronized void initView() { } @Override public void onDataArrived(Object data) { Log.i(TAG, data.toString()); }}
TestManager.java
package androidstudy.androidartstudy05.manager; import java.util.ArrayList;import java.util.List; /** * Created by Administrator on 2016/7/19. */public class TestManager { private List<OnDataArrivedListener> mOnDataArrivedListeners = new ArrayList<OnDataArrivedListener>(); private static class SingletonHolder { public static final TestManager INSTANCE = new TestManager(); } private TestManager() { } public static TestManager getInstance() { return SingletonHolder.INSTANCE; } public synchronized void registerListener(OnDataArrivedListener listener) { if (!mOnDataArrivedListeners.contains(listener)) { mOnDataArrivedListeners.add(listener); } } public synchronized void unregisterListener(OnDataArrivedListener listener) { mOnDataArrivedListeners.remove(listener); } public interface OnDataArrivedListener { public void onDataArrived(Object data); }}3、点击AndroidStudio界面的Monitor按钮打开DDMS界面,如下图所示,点击Dump HPROF file(红色框框标记)按钮导出一个hprof后缀的文件androidstudy.androidartstudy05.hprof保存到platform-tools下(放到此目录是为了下一步方便转换文件),我的路径为E:\Android\sdk\platform-tools
4、由于导出后的文件不能直接被MAT识别,所以需要通过hprof-conv命令转换一下,此命令是Android SDK提供的工具,位于platform-tools下,cmd命令切换到此目录后输入hprof-conv androidstudy.androidartstudy05.hprof androidstudy.androidartstudy05-conv.hprof命令回车, 会在platform-tools目录下生成一个androidstudy.androidartstudy05-conv.hprof文件,如下图:
5、打开MAT工具,导入转换后的文件androidstudy.androidartstudy05-conv.hprof,打开后界面如下:
6、点击“Histogram”按钮,展示界面如下,在红色框框中输入应用的包名androidstudy.androidartstudy05
7、通过下图结果可以看到MainActivity对象有三个(正常只会出现一个),很明显MainActivity存在内存泄漏
8、在MainActivity上点击右键->"Merge Shortest Paths To GC Roots"->"exclude all phantom/weak/soft etc.refrences"。
9、在打开的界面即可看到详细的引用详情
10、可以看到有三处引用了MainActivity对象,两处为单例对像列表(List<OnDataArrivedListener>)属性mOnDataArrivedListeners 持有,一处为静态变量private static Context sContext;持有
时间: 2024-10-09 00:39:52