LeakCanary 是什么?

LeakCanary是Square公司基于MAT开源的一个工具,用来检测Android App中的内存泄露问题。官方地址:https://github.com/square/leakcanary

工作原理分析:

1.怎么检测内存泄漏?什么时候去检测内存泄漏?

//注册生命周期  在onDestory 的时候 观察Activity 对象private final Application.ActivityLifecycleCallbacks lifecycleCallbacks =new ActivityLifecycleCallbacksAdapter() {@Override public void onActivityDestroyed(Activity activity) {//开始观察refWatcher.watch(activity);}};// 此方法为停止观察activity  也就是不在监听回掉public void stopWatchingActivities() {application.unregisterActivityLifecycleCallbacks(lifecycleCallbacks);}

自己去跟源码就会发现,LeakCanary 会 注册一个ActivityLifecycleCallbacks ,当监听到activity Ondestory 的时候,就会去观察这个activity 是不是泄漏了,有没有被GC回收。

具体怎么观察Activity 有没有被回收?

  /*** Watches the provided references and checks if it can be GCed. This method is non blocking,* the check is done on the {@link WatchExecutor} this {@link RefWatcher} has been constructed* with.** @param referenceName An logical identifier for the watched object.*/public void watch(Object watchedReference, String referenceName) {if (this == DISABLED) {return;}checkNotNull(watchedReference, "watchedReference");checkNotNull(referenceName, "referenceName");final long watchStartNanoTime = System.nanoTime();String key = UUID.randomUUID().toString();retainedKeys.add(key);final KeyedWeakReference reference =new KeyedWeakReference(watchedReference, key, referenceName, queue);ensureGoneAsync(watchStartNanoTime, reference);}Retryable.Result ensureGone(final KeyedWeakReference reference, final long watchStartNanoTime) {long gcStartNanoTime = System.nanoTime();long watchDurationMs = NANOSECONDS.toMillis(gcStartNanoTime - watchStartNanoTime);removeWeaklyReachableReferences();if (debuggerControl.isDebuggerAttached()) {// The debugger can create false leaks.return RETRY;}if (gone(reference)) {return DONE;}gcTrigger.runGc();removeWeaklyReachableReferences();if (!gone(reference)) {long startDumpHeap = System.nanoTime();long gcDurationMs = NANOSECONDS.toMillis(startDumpHeap - gcStartNanoTime);File heapDumpFile = heapDumper.dumpHeap();if (heapDumpFile == RETRY_LATER) {// Could not dump the heap.return RETRY;}long heapDumpDurationMs = NANOSECONDS.toMillis(System.nanoTime() - startDumpHeap);HeapDump heapDump = heapDumpBuilder.heapDumpFile(heapDumpFile).referenceKey(reference.key).referenceName(reference.name).watchDurationMs(watchDurationMs).gcDurationMs(gcDurationMs).heapDumpDurationMs(heapDumpDurationMs).build();heapdumpListener.analyze(heapDump);}return DONE;}

我们看到,观察activity 就是 把 activity 放到WeakRefence 里面,WeakReference 的第二个参数是一个Qeue 对象,我们手动执行一下GC,然后Qeue.pull 一下,看看Qeue 里面是不是有WeakRefence ,如果有说明对象被回收了。那么这个activity 就没有泄漏,否则就有可能泄露了导致回收不了。

这个机制是WeakReference 的机制。有兴趣可以自行了解一下。

怎么执行GC?

      Runtime.getRuntime().gc();enqueueReferences();System.runFinalization();

上面diam执行之后,我们再看下内存,还有没有activity 的实例,如果还有,那么说明这个activity 可能被泄露了。我们需要根据hprof 文件看下具体的调用链。

怎么生成hprof?

如果activity 内存泄露了,我们需要hprof 文件去分析。那么怎么拿到hprof?

Debug.dumpHprofData(heapDumpFile.getAbsolutePath());

怎么分析hprof

使用了下面的开源项目:

  implementation 'com.squareup.haha:haha:2.0.4'

分析完之后,用界面显示出来就没有什么好说了。

怎么在桌面有两个图标?

    <activityandroid:label="@string/app_name"android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/><category android:name="android.intent.category.DEFAULT"/></intent-filter></activity><activityandroid:theme="@style/leak_canary_LeakCanary.Base"android:name=".internal.DisplayLeakActivity"android:process=":leakcanary"android:enabled="false"android:label="@string/leak_canary_display_activity_label"android:icon="@mipmap/leak_canary_icon"android:taskAffinity="com.squareup.leakcanary.${applicationId}"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity>

我们发现,leackCanary会生成一个自己的桌面图标,点击进去可以查看内漏泄露的信息,而且不需要创建桌面快捷方式的权限,就可以做到,他是用上面的方式做到的。清单里面可以有多个"android.intent.category.LAUNCHER",当然也会有一个默认的。

怎么设置组件启用和关闭

  public static void setEnabledBlocking(Context appContext, Class<?> componentClass,boolean enabled) {ComponentName component = new ComponentName(appContext, componentClass);PackageManager packageManager = appContext.getPackageManager();int newState = enabled ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DISABLED;// Blocks on IPC.packageManager.setComponentEnabledSetting(component, newState, DONT_KILL_APP);}

也就这样啦,没有具体怎么分析hprof,有兴趣可以再深入研究了。

LeakCanary 源码解析相关推荐

  1. LeakCanary源码解析

    LeakCanary源码解析 本文我们来看下LeakCanary的源码,以下内容基于com.squareup.leakcanary:leakcanary-android:1.6.3 LeakCanar ...

  2. Android—内存泄漏、GC及LeakCanary源码解析

    内存抖动:内存频繁的分配和回收,频繁的GC会导致UI卡顿,严重的时候导致OOM. 内存泄露:程序在向系统申请分配内存空间后(new),在使用完毕后未释放.结果导致一直占据该内存单元,我们和程序都无法再 ...

  3. BAT高级架构师合力熬夜15天,肝出了这份PDF版《Android百大框架源码解析》,还不快快码住。。。

    前言 为什么要阅读源码? 现在中高级Android岗位面试中,对于各种框架的源码都会刨根问底,从而来判断应试者的业务能力边际所在.但是很多开发者习惯直接搬运,对各种框架的源码都没有过深入研究,在面试时 ...

  4. Android经典著名的百大框架源码解析(retrofit、Okhttp、Glide、Zxing、dagger等等)

    我们Android程序员每天都要和源码打交道.经过数年的学习,大多数程序员可以"写"代码,或者至少是拷贝并修改代码.而且,我们教授编程的方式强调编写代码的艺术,而不是如何阅读代码. ...

  5. 谷歌BERT预训练源码解析(二):模型构建

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...

  6. 谷歌BERT预训练源码解析(三):训练过程

    目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...

  7. 谷歌BERT预训练源码解析(一):训练数据生成

    目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...

  8. Gin源码解析和例子——中间件(middleware)

    在<Gin源码解析和例子--路由>一文中,我们已经初识中间件.本文将继续探讨这个技术.(转载请指明出于breaksoftware的csdn博客) Gin的中间件,本质是一个匿名回调函数.这 ...

  9. Colly源码解析——结合例子分析底层实现

    通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...

最新文章

  1. 信号完整性 带宽的确定
  2. mysql获取有哪几种状态_Mysql进阶垫脚石 -- Sql命令的执行状态有哪几种
  3. Sun副总裁:绿色数据中心需分四步走
  4. Graphviz之DT:手把手教你使用可视化工具Graphviz将dot文件转为结构图的pdf文件
  5. 协调器太多,cc2530的终端或则路由器选择性加入协调器的方法
  6. 总结Linux-ubuntu基本配置方法(远程连接,数据库,jdk,tomcat......)
  7. 计算机操作业务知识题库,《计算机操作基础知识题库》.doc
  8. bootstrap3中模态框的数据编辑使用方法
  9. 钉钉调岗申请单怎么写 钉钉申请调岗的教程
  10. 一个非常感人的爱情故事
  11. 远程调用python_远的解释|远的意思|汉典“远”字的基本解释
  12. linux awk,sort,uniq,wc,cut命令详解
  13. 【linux】16进制格式查看命令hexdump
  14. Exchange Server 2007邮箱存储服务器的容量规划和性能调优(下)
  15. foxmail 不知道这样的主机
  16. 微信前台WEUI前台实例+EXCEL导出,SSM框架完整流程
  17. 脚本录制软件python 按键精灵 tc_《脚》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...
  18. 【DC综合】逻辑综合的实施流程
  19. python爬取视频--下载2019巴菲特股东大会直播视频
  20. 常用SQL注入语句大全

热门文章

  1. mysql v8 漏洞_mysql'密码安全 - osc_v8gts6gd的个人空间 - OSCHINA - 中文开源技术交流社区...
  2. 和方舟rust一样的手游_方舟生存进化手游2.0版本的泰克科技有多强?恐龙大军都顶不住...
  3. matlab 中调用s函数表达式,[求助]S函数中能否调用M函数
  4. ANSYS报错Accelerations are exceeding internal limit解决方法
  5. java数据结构二叉树遍历_java数据结构 之 二叉树的遍历(1)
  6. WordPress 5.1 发布,监控古老 PHP 版本、编辑器性能提升
  7. ajax查找错误信息
  8. github远程提交简单入门
  9. EasyUI——常见用法总结
  10. [转]MongoDB基本使用