android性能跟踪分析工具系列 - LeakCanary

37624127_1408459495645.jpg

文集目录

ps:喜欢的点赞哦 android性能跟踪分析工具系列 - 目录


哈哈,LeakCanary我是啥我就不用说了吧,大名鼎鼎的 jack 大神出品的内存泄露分析工具,还不知道的小伙伴,看过这我的这篇介绍肯定就知道了,出去也好吹水去啦,哈哈哈......

LeakCanary 工具使用很简单,一步一步来就行了,不要有心里负担啊, 想着约 NB 的工具越难学啥的,都是瞎扯淡,好用的工具必须使用简单。

第一步添加 gradle 依赖

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'

第二部使用

在自定义的 application 中初始化 LeakCanary

public class LeakCanaryApplication extends Application {

  private RefWatcher mRefWatcher;

  @Override
  public void onCreate() {
      super.onCreate();
      mRefWatcher = LeakCanary.install(this);
  }

好了最简单的使用方式就是这样的,看下我的测试demo,application 持有一个 activity 对象,一个最简单的activity 对象内存谢落

public class BActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);

        MyApplication.getInstance().mActivity = this;

    }

然后我们怎么看结果呢,这个和一般的还不一样,要是发生内存泄露,先是会有一个 toast 实体,然后会在桌面上生成一个 LeakCanary 图标,并且会一条通知,我的手机不知道为啥就是收不到通知。我们点击这个 LeakCanary 图标就可以看到具体的信息,这个不要着急,要等一会才有,另外期中的信息会持久保存,不想看以前的可以删掉。


Snip20170917_36.png

我们点击这一条提示,可以看到具体的引用关系


Snip20170917_37.png

这个结果很明显了吧,不过吐槽下,LeakCanary 提示到时快,但是显示内容实在太慢了,我这2-3分钟才出来,大家要耐心......


必须要吐槽

LeakCanary 的确是傻瓜式的,但是太慢,而且默认只是检测 activity 对象,想要检测别的对象,比如fragment 或是大体积集合,就得另写

我们需要获取 LeakCanary 的核心 RefWatcher,就是监视对象用来分析内存泄露,并持有待分析对象的引用

我们在 application 获取 RefWatcher

public class MyApplication extends Application {

    public static MyApplication mApplication;

    public Activity mActivity;
    public List mList;
    public RefWatcher mWatche;

    @Override
    public void onCreate() {
        super.onCreate();
        this.mApplication = this;
        this.mApplication.mWatche = LeakCanary.install(this);
    }

    public static MyApplication getInstance() {
        return mApplication;
    }
}

然后我们在页面的销毁生命周期里注册需要观察分析的对象,至于为啥卸载生命周期里,因为这时候我们才要分析啊,我们的注册动作其实就是触发内存泄露分析了

public class BActivity extends AppCompatActivity {

    private ArrayList<String> mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);

             MyApplication.getInstance().mActivity = this;

        mList = new ArrayList<>(10000);
        MyApplication.getInstance().mList = mList;

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        MyApplication.getInstance().mWatche.watch(this);
        MyApplication.getInstance().mWatche.watch(mList);
    }

这里我们泄露了一个 activity 和 一个集合对象,不过很遗憾,10次里也就1次能抓到这个集合的内存的泄露,而且速度非常之慢,是在无语了。知道为啥不,因为 LeakCanary 一次只能抓一个内存泄露。然后呢我改成只有集合内存泄露,但是呢,抓是抓到了,但是太他娘的慢了


Snip20170917_39.png
Snip20170917_41.png

引用列表里,没有显示是哪个 activity,由于结果显示的非常之慢,我都不知道这个列表是在哪个 activity 泄露的,要是有多个地方都会有这个数据交互,那还真不知道是谁泄露的。所以我觉得这个工具只适合观察 activity / fragment 对象

另外LeakCanary可以设置一个回调,在抓到内存泄露后会执行一个我们指定的 intentServer

  • 第一步:继承DisplayLeakService,进行自己的处理逻辑,这里我们只是打印出泄漏的信息,heapDump为对应的内存快照,result为分析的结果,leakInfo则是相关的信息
public class MyLeakUploadService extends DisplayLeakService {

    @Override
    protected void afterDefaultHandling(HeapDump heapDump, AnalysisResult result, String leakInfo) {
        if (!result.leakFound || result.excludedLeak) {
            return;
        }
        Log.d("MyLeakUploadService", "leakInfo=" + leakInfo);
    }

}
  • 第二步:改变Application中初始化RefWatcher的方式,第二个参数中传入我们自定义的Service类名:
public class LeakCanaryApplication extends Application {
    private RefWatcher mRefWatcher;
    @Override
    public void onCreate() {
        super.onCreate();
        mRefWatcher = LeakCanary.install(this, MyLeakUploadService.class);
    }
}

优点:

  • 天然对 activity 很友好
  • 傻瓜式,测试都能玩,在手机上页方便查看

缺点:

  • 内容显示是在太慢,没办法 LeakCanary 是在主线程的任务队列中添加了一个级别很低的任务来进行内存分析,所以速度很慢。
  • 对于非 activity 对象的分析效果实在烂,上面这个集合对象的内存泄露,10次里也就分析初一次,显示速度那就更无语了
  • 默认只能分析 activity 对象,非 activity 对象需要自己添加到 watche 里,太麻烦了,失去了抓取的自主性啊,变成手动的 LeakCanary 又有多大意义呢。

结论呢

这个 LeakCanary 平时放里面就好了,测试app 没事时候看一看就得了,完全指望这个不现实,还是自己抓内存快照去扒拉扒拉靠谱,比这快多了。LeakCanary 用作补充即可。

话说还是看接下来的内存分析工具吧,比等着 LeakCanary 慢悠悠的一次给你一条建议,还是自己去抓下内存快照看下来的精准,速度的多。

ps:上面都是我个人的想法,限于使用 LeakCanary 日短,有错误请留言给我,谢谢啦!


参考资料:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容