用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方法有沒有正確調用即可。


 

 

 

 

 

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