android内存分析工具MAT的使用

android内存分析工具MAT的使用

当遇到OutOfMemory问题的时候,怎么样通过MAT来定位和分析问题呢?先看个例子:

public class MemoryLeakActivity extends AppCompatActivity{
  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_memory_leak);

    handler.sendEmptyMessageDelayed(0, 10000);
  }

  Handler handler = new Handler() {
    @Override public void handleMessage(Message msg) {
      super.handleMessage(msg);
    }
  };
}

代码中内存泄露的原因是匿名内部类创建的对象hander持有外部activity的引用,导致activity无法及时销毁。
我们来做个简单的测试,先运行程序,启动和退出MemoryLeakActivity三次,然后点击卡车icon触发GC释放内存,再点击Dump Java Heap按钮,生成xxx.hprof文件,如下图:

生成xxx.hprof文件后,点击右侧Analyser Tasks分析是否存在内存泄露问题,如下图:

我们发现MemoryLeakActivity存在内存泄露的问题,可是具体什么原因导致MemoryLeakActivity内存泄露呢?MAT这个时候可以登场了,首先对xx.hprof文件格式转化下,否则MAT无法识别,当然如果你用的是eclipse,并且安装了mat插件,应该是不用转换也能识别的,这里以AndroidStudio为例,我们先转换下hprof文件格式,如下图。

MAT上哪找呢?下载地址:http://www.eclipse.org/mat/downloads.php
按装启动MAT后,打开格式转换后的xx.hprof文件,点开Histogram查看对象数量和分配的内存大小,理解下Shallow Heap & Retained Heap这两个概念:

  • Shallow Heap
    是对象本身占据的内存的大小,不包含其引用的对象
  • Retained Heap
    当前对象大小+当前对象可直接或间接引用到的对象的大小总和

在ClassName一列输入关键字检索MemoryLeakActivity,查找MemoryLeakActivity被哪些对象引用,这里又要了解下:

  • with incoming references
    显示选中对象被哪些对象持有
  • with outgoing references
    显示选中对象持有了哪些外部对象

这里我们选择with incoming references,查看MemoryLeakActivity被哪些对象持有,导致MemoryLeakActivity无法正常销毁。

检索出3个MemoryLeakActivity对象,和之前启动3次对应,正常情况下是Activity调用onDestory后被系统回收,可是3个MemoryLeakActivity都在,选择其中一个Activity按照下图操作,检索与RC Roots关联的引用,虚/软/弱引用除外。

内存泄露的本质是:当对象逻辑上需要被销毁,却仍然和RC Roots存在引用链关系,导致GC无法回收

终于找到了,handle持有activity引用导致的内存泄露。


下面再补充下解决方法(静态内部类+弱引用):

public class MemoryLeakActivity extends AppCompatActivity{
  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_memory_leak);

    handler.sendEmptyMessageDelayed(0, 10000);
  }

 static class MyHander extends Handler {

    WeakReference<Activity> activityWeakReference;
    public MyHander(Activity activity) {
      activityWeakReference = new WeakReference<Activity>(activity);
    }
    @Override public void handleMessage(Message msg) {
      super.handleMessage(msg);
    }
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chengyuan9160

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值