用mat工具分析Android泄漏解决问题

在项目开发过程中遇到了一个内存泄漏的问题。使用mat工具进行排查,以下是排查过程

1.首先是leakcanary上提示报错

2.打行Androidstudio Profile.  菜单View-》ToolWindow-》Profiler (android studio 3.4版本)

3.运行程序

4.在出现问题的页面来回切换

5.点击Profiler的gc

6.Dump java heap 

7.在下方的Head Dump里面选择 app heap 然后 arrange by package 输入自己项目的包名

发现SecondActivity的Allocations数量竟然等于7!说明存在SecondActivity的内存泄漏,使得SecondActivity的实例不被回收

8.Export Heap Dump到指定目录,然后从官网上下载MAT(一款eclipse下面的内存分析工具),具体网址:https://www.eclipse.org/mat/downloads.php

mat工具下载好以后在mac环境下面报以下错误:

解决方案如下:

https://yq.aliyun.com/articles/642590

9.打开MAT并且导入刚才我们防止的dump 文件。

刚开始导入的时候会报错,这时候需要将dump进行转换,找到Androidsdk目录下platform-tools文件夹,里面有个hprof-conv工具,使用这个工具将dump文件转化为mat支持打开的格式。然后用mat成功打开dump文件后,选择Histogram选项卡

10.在红框处输入过滤条件

 

选择排除任何 软引用、虚引用等

11.

typesBySubscriber是EventBus的内部成员,这个可以EventBus里面的源码可以看到

public class EventBus {

    /** Log tag, apps may override it. */
    public static String TAG = "EventBus";

    static volatile EventBus defaultInstance;

    private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
    private static final Map<Class<?>, List<Class<?>>> eventTypesCache = new HashMap<>();

    private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
    private final Map<Object, List<Class<?>>> typesBySubscriber;
    private final Map<Class<?>, Object> stickyEvents;

这个可以从EventBus的源码可以知道,typesBySubscriber是在构造器里面赋值,然后在register方法里面添加内容,在unregister方法里面清空内容。所以造成内存泄漏的原因就是EventBus的unregister方法没有正确调用。具体可以到代码里面排查下EventBus的unregister方法有没有正确调用即可。


 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章