Kotlin Android LeakCanary内存泄漏检测实战
在Kotlin Android应用中使用LeakCanary检测内存泄漏的步骤如下:
1. 添加依赖
在模块的build.gradle
文件中添加LeakCanary依赖:
dependencies {debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' // 使用最新版本
}
2. 自动初始化(无需额外代码)
LeakCanary 2.x及以上版本会自动初始化,无需手动配置。确保应用启动时加载了Application
类即可。
3. 制造内存泄漏(测试)
创建存在内存泄漏的Activity:
class LeakyActivity : AppCompatActivity() {companion object {var leakedContext: Context? = null // 静态引用导致泄漏}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)leakedContext = this // 错误:静态变量持有Activity实例}
}
4. 触发检测
运行应用,进入LeakyActivity
后退出。LeakCanary会自动检测泄漏,并在通知栏提示。
5. 分析报告
点击通知查看泄漏轨迹,报告会显示泄漏对象的引用链。例如:
┬───
│ GC Root: System class
│
├─ LeakyActivity class
│ Leaking: NO (a class is never leaking)
│ ↓ static LeakyActivity.leakedContext
│ ~~~~~~~~~~~~~~
╰→ LeakyActivity instanceLeaking: YES (ObjectWatcher was watching this)
报告指出leakedContext
静态变量导致泄漏。
6. 修复泄漏
在onDestroy
中清除引用:
override fun onDestroy() {super.onDestroy()leakedContext = null // 释放引用
}
7. 自定义配置(可选)
在自定义Application
类中调整LeakCanary:
class MyApp : Application() {override fun onCreate() {super.onCreate()LeakCanary.config = LeakCanary.config.copy(retainedVisibleThreshold = 3, // 触发堆转储前保留的可见实例数referenceMatchers = listOf(IgnoredReferenceMatcher(pattern = "com.example.IgnoredClass" // 忽略特定类)))}
}
8. 高级场景
- Fragment监测:LeakCanary默认支持Fragment销毁后的泄漏检测。
- 自定义对象监控:手动观察对象:
val watchedObject = SomeObject() LeakCanary.watch(watchedObject,description = "SomeObject should be garbage collected" )
9. 注意事项
- 性能影响:仅在
debug
构建中使用,避免影响生产环境性能。 - 及时处理泄漏:修复报告中优先级高的泄漏,避免累积问题。
- 持续集成:可通过
LeakCanary
的JUnit规则在自动化测试中检测泄漏。
10. 常见泄漏场景及修复
- 静态Context引用:改用
ApplicationContext
或弱引用。 - 未注销监听器:在生命周期结束时注销(如
onDestroy
)。 - Handler/Runnable延迟任务:使用
WeakReference
或View.postDelayed
并清理回调。
通过以上步骤,可有效利用LeakCanary识别和修复内存泄漏,提升应用稳定性和性能。