LeakCanary 源码解析
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 源码解析相关推荐
- LeakCanary源码解析
LeakCanary源码解析 本文我们来看下LeakCanary的源码,以下内容基于com.squareup.leakcanary:leakcanary-android:1.6.3 LeakCanar ...
- Android—内存泄漏、GC及LeakCanary源码解析
内存抖动:内存频繁的分配和回收,频繁的GC会导致UI卡顿,严重的时候导致OOM. 内存泄露:程序在向系统申请分配内存空间后(new),在使用完毕后未释放.结果导致一直占据该内存单元,我们和程序都无法再 ...
- BAT高级架构师合力熬夜15天,肝出了这份PDF版《Android百大框架源码解析》,还不快快码住。。。
前言 为什么要阅读源码? 现在中高级Android岗位面试中,对于各种框架的源码都会刨根问底,从而来判断应试者的业务能力边际所在.但是很多开发者习惯直接搬运,对各种框架的源码都没有过深入研究,在面试时 ...
- Android经典著名的百大框架源码解析(retrofit、Okhttp、Glide、Zxing、dagger等等)
我们Android程序员每天都要和源码打交道.经过数年的学习,大多数程序员可以"写"代码,或者至少是拷贝并修改代码.而且,我们教授编程的方式强调编写代码的艺术,而不是如何阅读代码. ...
- 谷歌BERT预训练源码解析(二):模型构建
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...
- 谷歌BERT预训练源码解析(三):训练过程
目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...
- 谷歌BERT预训练源码解析(一):训练数据生成
目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...
- Gin源码解析和例子——中间件(middleware)
在<Gin源码解析和例子--路由>一文中,我们已经初识中间件.本文将继续探讨这个技术.(转载请指明出于breaksoftware的csdn博客) Gin的中间件,本质是一个匿名回调函数.这 ...
- Colly源码解析——结合例子分析底层实现
通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...
最新文章
- 信号完整性 带宽的确定
- mysql获取有哪几种状态_Mysql进阶垫脚石 -- Sql命令的执行状态有哪几种
- Sun副总裁:绿色数据中心需分四步走
- Graphviz之DT:手把手教你使用可视化工具Graphviz将dot文件转为结构图的pdf文件
- 协调器太多,cc2530的终端或则路由器选择性加入协调器的方法
- 总结Linux-ubuntu基本配置方法(远程连接,数据库,jdk,tomcat......)
- 计算机操作业务知识题库,《计算机操作基础知识题库》.doc
- bootstrap3中模态框的数据编辑使用方法
- 钉钉调岗申请单怎么写 钉钉申请调岗的教程
- 一个非常感人的爱情故事
- 远程调用python_远的解释|远的意思|汉典“远”字的基本解释
- linux awk,sort,uniq,wc,cut命令详解
- 【linux】16进制格式查看命令hexdump
- Exchange Server 2007邮箱存储服务器的容量规划和性能调优(下)
- foxmail 不知道这样的主机
- 微信前台WEUI前台实例+EXCEL导出,SSM框架完整流程
- 脚本录制软件python 按键精灵 tc_《脚》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...
- 【DC综合】逻辑综合的实施流程
- python爬取视频--下载2019巴菲特股东大会直播视频
- 常用SQL注入语句大全
热门文章
- mysql v8 漏洞_mysql'密码安全 - osc_v8gts6gd的个人空间 - OSCHINA - 中文开源技术交流社区...
- 和方舟rust一样的手游_方舟生存进化手游2.0版本的泰克科技有多强?恐龙大军都顶不住...
- matlab 中调用s函数表达式,[求助]S函数中能否调用M函数
- ANSYS报错Accelerations are exceeding internal limit解决方法
- java数据结构二叉树遍历_java数据结构 之 二叉树的遍历(1)
- WordPress 5.1 发布,监控古老 PHP 版本、编辑器性能提升
- ajax查找错误信息
- github远程提交简单入门
- EasyUI——常见用法总结
- [转]MongoDB基本使用