LeakCanary

23 阅读4分钟

1、LeakCanary 是什么

答案

LeakCanary 是 Square 开源的 Android 内存泄漏检测工具,集成到项目后,自动监控、自动抓取内存泄漏、自动分析泄漏链、弹窗展示详情,帮助开发快速定位内存泄漏问题。

2、LeakCanary 能检测哪些泄漏

答案

  • Activity 泄漏
  • Fragment 泄漏
  • 静态变量持有页面引用
  • 单例持有 Activity/Context
  • 匿名内部类、Handler 延时任务
  • 线程、协程未取消持有页面
  • 监听未注销、集合未移除引用
  • Bitmap、资源未释放等

3、LeakCanary 工作原理(核心必背)

答案

1. 监听生命周期

自动监听 Activity、Fragment 的 onDestroy

2. 弱引用 + 引用队列

页面销毁后,用 WeakReference 持有对象,关联 ReferenceQueue

3. 触发 GC

页面销毁延迟一段时间后,手动触发 GC

4. 判断是否回收

如果对象还没被回收,判定为内存泄漏

5. dump 堆内存

生成 hprof 堆快照,分析引用链,找出是谁持有导致无法回收。

6. 解析展示

自动分析泄漏路径,弹窗显示泄漏原因和引用链。

4、WeakReference 弱引用作用

答案

弱引用不阻止 GC 回收

若无其他强引用,GC 时会直接回收;

LeakCanary 靠弱引用判断页面是否被正常释放。

5、ReferenceQueue 引用队列作用

答案

当弱引用对象被 GC 回收后,会自动进入引用队列

LeakCanary 通过队列判断:是否已被回收,快速判定泄漏。

6、为什么要手动触发 GC

答案

为了排除临时引用、还没来得及 GC的情况;

主动触发 GC 后还不能释放,才是真泄漏,避免误判。

7、LeakCanary 会不会影响性能

答案开发环境开启,线上关闭即可;检测、dump 堆分析只在debug执行,正式包可以依赖 leakcanary-android-no-op 空实现,完全无性能影响

8、常见内存泄漏场景及怎么修复

答案

  1. 静态持有 Activity/Fragment修复:不要静态存页面引用,改用 Application 上下文。
  2. Handler 延时消息、postDelay修复:页面销毁 removeCallbacks,使用 viewModelScope/lifecycleScope
  3. 匿名内部类 / 异步线程修复:用静态内部类、弱引用,页面销毁终止线程。
  4. 监听、广播、回调未注销修复:onDestroy 反注册、移除监听。
  5. 单例持有页面修复:单例只持 Application Context,不持页面。
  6. 集合容器长期持有对象修复:页面退出及时 clear、移除元素。

9、LeakCanary 和 Android Studio Profiler 区别

答案

  • LeakCanary:自动检测、自动分析泄漏链、定位代码位置,适合日常开发查泄漏。
  • Profiler:手动看内存曲线、手动 dump 堆,需要自己分析引用链,适合深度性能排查。

10、怎么规避和解决内存泄漏(通用套路)

答案

  1. 尽量使用 Application Context 代替页面 Context;
  2. 避免静态变量持有 Activity/Fragment;
  3. 异步任务、协程、定时器页面销毁及时取消
  4. 广播、监听、回调、观察者页面销毁反注册
  5. 用 Lifecycle、lifecycleScope 自动管理生命周期;
  6. 集合不用及时清空,不用的引用手动置空;
  7. 开发一直开启 LeakCanary,及时修复泄漏。

11、面试一句话总结

LeakCanary 依靠监听页面生命周期 + 弱引用 + 引用队列 + 手动 GC + 堆快照分析,自动检测 Activity、Fragment 等内存泄漏,解析引用链弹窗提示;开发阶段自动排查常见泄漏场景,正式版可关闭无性能损耗,是 Android 开发必备查内存泄漏工具。

12、LeakCanary 工作原理 通俗大白话版

我给你用最接地气、面试官一听就懂的方式讲:

1. 先盯着页面生命周期

Activity、Fragment 一关(走了 onDestroy),LeakCanary 马上知道:这个页面该被销毁、该被回收了

2. 给这个页面包一层弱引用

就像给这个页面贴个标签,用弱引用拿着它。

弱引用特点:没人强引用拽着它,GC 一扫描就直接回收

3. 等一会儿,主动触发一次 GC

页面销毁后稍等一下,LeakCanary 手动催系统赶紧 GC

意思就是:该清的赶紧清掉。

4. 判断:回收掉没?
  • 如果回收了:正常,没泄漏。
  • 如果还没回收:说明有地方死死拽着这个页面不放,就是内存泄漏。
5. 抓取堆内存,查是谁拽着不放

一旦判定泄漏,立刻保存整个内存快照,然后自动分析引用链

到底是 Handler、静态变量、单例、线程、监听 哪个家伙还拿着页面不放。

6. 最后弹窗告诉你

把泄漏路径、哪行代码有问题、引用链条,直接弹窗展示给开发者看。


极简一句话背诵版

LeakCanary 就是:页面销毁时用弱引用包住它,手动触发 GC,如果还回收不掉就判定内存泄漏,再抓取堆内存分析引用链,自动找出是谁持有引用导致无法释放。