今天楼主遇到引用LeakCanary时代码跟官网一样但是就不弹出来。楼主新建项目就可以正常使用。楼主郁闷半天,现在终于整出来了。

楼主主工程app引用module为thirdParty,本想为了整洁三方的都扔进这个thirdParty 结果导致了这个没弄出来。

1.写一个application :

  1. <application
  2. android:name=".BaseApplication"
  1. public class BaseApplication extends Application {
  2. private static BaseApplication app;
  3. private DaoMaster daoMaster;
  4. private DaoSession daoSession;
  5. private SQLiteDatabase db;
  6. private String TAG="BaseApplication";
  7. @Override
  8. public void onCreate() {
  9. super.onCreate();
  10. Log.i(TAG, "onCreate: ");
  11. app = this;
  12. LeakCanary.install(this);
  13. initDB();
  14. }

2.写一段让程序泄露的代码:

  1. void startAsyncTask() {
  2. // This async task is an anonymous class and therefore has a hidden reference to the outer
  3. // class MainActivity. If the activity gets destroyed before the task finishes (e.g. rotation),
  4. // the activity instance will leak.
  5. new AsyncTask<Void, Void, Void>() {
  6. @Override
  7. protected Void doInBackground(Void... params) {
  8. // Do some slow work in background
  9. SystemClock.sleep(200000);
  10. return null;
  11. }
  12. }.execute();
  13. Toast.makeText(this, "请关闭这个A完成泄露", Toast.LENGTH_SHORT).show();
  14. }

3.添加build.gradle 由于我把所有的依赖都写在的thirdParty这个lib中

仔细观察一下这个引用不太一样:

我们平时引用都是:

  1. compile 'com.github.lzyzsd.randomcolor:library:1.0.0'

而LeakCanary的引用是:

  1. debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'

后来我又写到了主app中 结果可以使用了。。。

查了一下他们的含义:

Compile

compile是对所有的build type以及favlors都会参与编译并且打包到最终的apk文件中。

Provided

Provided是对所有的build type以及favlors只在编译时使用,类似eclipse中的external-libs,只参与编译,不打包到最终apk。

APK

只会打包到apk文件中,而不参与编译,所以不能再代码中直接调用jar中的类或方法,否则在编译时会报错

Test compile

Test compile 仅仅是针对单元测试代码的编译编译以及最终打包测试apk时有效,而对正常的debug或者release apk包不起作用。

Debug compile

Debug compile 仅仅针对debug模式的编译和最终的debug apk打包。

Release compile

Release compile 仅仅针对Release 模式的编译和最终的Release apk打包。

还不太清楚为啥。。。但是给大家提个醒。

下面转一个非常好的文章:http://droidyue.com/blog/2016/03/28/android-leakcanary/

懒人可以看我下面的转载

Android内存泄漏检测利器:LeakCanary

MAR 28TH, 2016

是什么?

一言以蔽之:LeakCanary是一个傻瓜化并且可视化的内存泄露分析工具

为什么需要LeakCanary?

因为它简单,易于发现问题,人人可参与。

  • 简单:只需设置一段代码即可,打开应用运行一下就能够发现内存泄露。而MAT分析需要Heap Dump,获取文件,手动分析等多个步骤。
  • 易于发现问题:在手机端即可查看问题即引用关系,而MAT则需要你分析,找到Path To GC Roots等关系。
  • 人人可参与:开发人员,测试测试,产品经理基本上只要会用App就有可能发现问题。而传统的MAT方式,只有部分开发者才有精力和能力实施。

如何集成

尽量在app下的build.gradle中加入以下依赖

1
2
3
4
5
 dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' // or 1.4-beta1
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta1
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta1
}

在Application中加入类似如下的代码

1
2
3
4
5
6
7
public class ExampleApplication extends Application {

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

到这里你就可以检测到Activity的内容泄露了。其实现原理是设置Application的ActivityLifecycleCallbacks方法监控所有Activity的生命周期回调。内部实现代码为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public final class ActivityRefWatcher {
private final ActivityLifecycleCallbacks lifecycleCallbacks = new ActivityLifecycleCallbacks() {
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
} public void onActivityStarted(Activity activity) {
} public void onActivityResumed(Activity activity) {
} public void onActivityPaused(Activity activity) {
} public void onActivityStopped(Activity activity) {
} public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
} public void onActivityDestroyed(Activity activity) {
ActivityRefWatcher.this.onActivityDestroyed(activity);
}
};
private final Application application;
private final RefWatcher refWatcher; public static void installOnIcsPlus(Application application, RefWatcher refWatcher) {
if(VERSION.SDK_INT >= 14) {
ActivityRefWatcher activityRefWatcher = new ActivityRefWatcher(application, refWatcher);
activityRefWatcher.watchActivities();
}
}
....
}

想要检测更多?

首先我们需要获得一个RefWatcher,用来后续监控可能发生泄漏的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MyApplication extends Application {
private static RefWatcher sRefWatcher; @Override
public void onCreate() {
super.onCreate();
sRefWatcher = LeakCanary.install(this);
} public static RefWatcher getRefWatcher() {
return sRefWatcher;
}
}

监控某个可能存在内存泄露的对象

1
MyApplication.getRefWatcher().watch(sLeaky);

哪些需要进行监控

默认情况下,是对Activity进行了检测。另一个需要监控的重要对象就是Fragment实例。因为它和Activity实例一样可能持有大量的视图以及视图需要的资源(比如Bitmap)即在Fragment onDestroy方法中加入如下实现

1
2
3
4
5
6
7
public class MainFragment extends Fragment {
@Override
public void onDestroy() {
super.onDestroy();
MyApplication.getRefWatcher().watch(this);
}
}

其他也可以监控的对象

  • BroadcastReceiver
  • Service
  • 其他有生命周期的对象
  • 直接间接持有大内存占用的对象(即Retained Heap值比较大的对象)

何时进行监控

首先,我们需要明确什么是内存泄露,简而言之,某个对象在该释放的时候由于被其他对象持有没有被释放,因而造成了内存泄露。

因此,我们监控也需要设置在对象(很快)被释放的时候,如Activity和Fragment的onDestroy方法。

一个错误示例,比如监控一个Activity,放在onCreate就会大错特错了,那么你每次都会收到Activity的泄露通知。

如何解决

常用的解决方法思路如下

  • 尽量使用Application的Context而不是Activity的
  • 使用弱引用或者软引用
  • 手动设置null,解除引用关系
  • 将内部类设置为static,不隐式持有外部的实例
  • 注册与反注册成对出现,在对象合适的生命周期进行反注册操作。
  • 如果没有修改的权限,比如系统或者第三方SDK,可以使用反射进行解决持有关系

加入例外

有些特殊情况,我们需要忽略一些问题,这时候就需要添加例外规则。比如ExampleClass.exampleField会导致内存泄漏,我们想要忽略,如下操作即可。

1
2
3
4
5
6
7
8
9
// ExampleApplication is defined in "Customizing and using the no-op dependency"
public class DebugExampleApplication extends ExampleApplication {
protected RefWatcher installLeakCanary() {
ExcludedRefs excludedRefs = AndroidExcludedRefs.createAppDefaults()
.instanceField("com.example.ExampleClass", "exampleField")
.build();
return LeakCanary.install(this, DisplayLeakService.class, excludedRefs);
}
}

如何实现的

LeakCanary实际上就是在本机上自动做了Heap dump,然后对生成的hprof文件分析,进行结果展示。和手工进行MAT分析步骤基本一致。

如何不影响对外版APK

是的,这个问题确实值得关注,因为LeakCanary确实是影响程序运行的,尤其是heap dump操作,不过好在这件事Square已经考虑了,即在我们增加依赖时

1
2
3
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' // or 1.4-beta1
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta1
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' // or 1.4-beta1

其中releaseCompile和testCompile这两个的依赖明显不同于debugCompile的依赖。它们的依赖属于NOOP操作。

NOOP,即No Operation Performed,无操作指令。常用的编译器技术会检测无操作指令并出于优化的目的将无操作指令剔除。

因而,只要配置好releaseCompile和testCompile的依赖,就无需担心对外版本的性能问题了。

实践中的问题

  • 如果targetSdkVersion为23,在6.0的机器上会存在问题,卡死,因为LeakCanary并没有很好支持Marshmallow运行时权限,所以始终得不到sd卡权限,进而导致卡死。

注意

  • 目前LeakCanary一次只能报一个泄漏问题,如果存在内存泄漏但不是你的模块,并不能说明这个模块没有问题。建议建议将非本模块的泄漏解决之后,再进行检测。

Anroid中内存泄漏相关文章

使用LeakCanary遇到的问题 就是不弹出来的更多相关文章

  1. Android性能优化之利用LeakCanary检测内存泄漏及解决办法

    前言: 最近公司C轮融资成功了,移动团队准备扩大一下,需要招聘Android开发工程师,陆陆续续面试了几位Android应聘者,面试过程中聊到性能优化中如何避免内存泄漏问题时,很少有人全面的回答上来. ...

  2. Android内存泄漏检测利器:LeakCanary

    Android内存泄漏检测利器:LeakCanary MAR 28TH, 2016 是什么? 一言以蔽之:LeakCanary是一个傻瓜化并且可视化的内存泄露分析工具 为什么需要LeakCanary? ...

  3. LeakCanary,30分钟从入门到精通

    简述 在性能优化中,内存是一个不得不聊的话题:然而内存泄漏,显示已经成为内存优化的一个重量级的方向.当前流行的内存泄漏分析工具中,不得不提的就是LeakCanary框架:这是一个集成方便, 使用便捷, ...

  4. 内存测试——内存泄露工具 LeakCanary

    项目地址 https://github.com/square/leakcanary 接入方法 1. 配置依赖 dependencies { debugCompile 'com.squareup.lea ...

  5. 【android】通过leakCanary找出程序内存泄露点

    背景 内存泄露是咱新手比较头痛的问题,因为它不像崩溃,在开发环境可以根据提示的错误信息排查问题. 你都不知道咱的app是否哪个犄角旮旯藏着一个吞噬内存的黑洞. 排查android 内存泄露比较底层高端 ...

  6. android 内存泄漏检测工具 LeakCanary 泄漏金丝雀

    韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 内存泄漏检测工具 android 内存泄漏检测工具 ======== 内存泄漏 就是  无用的对 ...

  7. Android内存优化8 内存检测工具2 LeakCanary——直白的展现Android中的内存泄露

    之前碰到的OOM问题,终于很直白的呈现在我的眼前:我尝试了MAT,但是发现不怎么会用.直到今天终于发现了这个新工具: 当我们的App中存在内存泄露时会在通知栏弹出通知: 当点击该通知时,会跳转到具体的 ...

  8. Android内存泄漏排查利器LeakCanary

    开源地址:https://github.com/square/leakcanary 在 build.gralde 里加上依赖, 然后sync 一下, 添加内容如下 dependencies { ... ...

  9. LeakCanary——直白的展现Android中的内存泄露

    之前碰到的OOM问题,终于很直白的呈现在我的眼前:我尝试了MAT,但是发现不怎么会用.直到今天终于发现了这个新工具: 当我们的App中存在内存泄露时会在通知栏弹出通知: 当点击该通知时,会跳转到具体的 ...

随机推荐

  1. 设计模式之第9章-原型模式(Java实现)

    设计模式之第9章-原型模式(Java实现) “快到春节了,终于快放假了,天天上班好累的说.”“确实啊,最近加班比较严重,项目快到交付了啊.”“话说一到过节,就收到铺天盖地的短信轰炸,你说发短信就发吧, ...

  2. MFC定时关机程序的实现2-添加启动项到注册表

    虽然上一篇实现了的定时关机,但是还不够完善,比如开机自动启动,然后按照配置的时间定时关机,并最小化到任务栏. 先来说开机启动怎么实现,开机启动实现的方法有好几种,比如直接在开始菜单启动项里添加一个程序 ...

  3. 接口测试之post和get的区别

    post和get都可以给服务器发送请求,在做接口测试的时候,我发现有些时候某些功能的接口文档中是用post请求发送的, 但是只要接口一致参数一致用post也能发送请求,并且获取到的返回也是正确的. 那 ...

  4. [ecmagnet][python基础]有关git那些事

    #1 git教程 # 注册git服务器用户,权限-- 注意这个和客户端用户不是一样 # 客户端(linux)提交代码到本地仓库(简单版,了解原理) a.安装git sudo apt-get insta ...

  5. [笔记]《算法图解》第十章 K最近邻算法

    K最近邻算法 简称KNN,计算与周边邻居的距离的算法,用于创建分类系统.机器学习等. 算法思路:首先特征化(量化) 然后在象限中选取目标点,然后通过目标点与其n个邻居的比较,得出目标的特征. 余弦相似 ...

  6. mysql event 学习

    mysql 通过事件可以实现定时任务 : 1. 检查你的MYSQL是否开了这个功能 show variables like "%scheduler" //注意 最后是er 2.   ...

  7. REDIS基础笔记

    Redis基础笔记 资源链接 简介 简介 安装 五种数据类型及相应命令 1. 字符串类型 2. 散列类型 3. 列表类型 4. 集合类型 5. 有序集合 其他 事务 SORT 生存时间 任务队列 发布 ...

  8. Dos中查看mysql数据时 中文乱码

    使用jsp页面查看数据时可以正确显示中文,但是dos窗口查看数据时中文显示乱码. 上网查了一下原因:之所以会显示乱码,就是因为MySQL客户端输出窗口显示中文时使用的字符编码不对造成的,可以使用如下的 ...

  9. 论文笔记《Fully Convolutional Networks for Semantic Segmentation》

    一.Abstract 提出了一种end-to-end的做semantic segmentation的方法,也就是FCN,是我个人觉得非常厉害的一个方法. 二.亮点 1.提出了全卷积网络的概念,将Ale ...

  10. android2.2 watchdog分析

    1 watchdog分析 Watchdog就是“看门狗”.其最初存在的意义是因为以前嵌入式设备上的程序经常跑飞(电磁干扰之类的),所以专门设置了一个硬件看门狗,每个一段时间,看门狗就去检查一下某个参数 ...