常见问题¶
Android SDK 会导致泄漏吗?¶
是的。AOSP 以及制造商实现中,随着时间推移修复了许多已知的内存泄漏。当发生此类泄漏时,作为应用开发者几乎无能为力。因此,LeakCanary 内置了一个已知 Android 泄漏的列表,以便识别,这称为库泄漏(参见 泄漏分类)。
如果您发现新的泄漏,请 创建一个 issue(选择 🤖Android SDK / support library 中的泄漏)并按照以下步骤操作:
- 提供完整的泄漏路径信息(包括元数据),并使用反引号 (`) 进行格式化。
- 阅读该版本 Android 的 AOSP 源码,尝试找出原因。您可以通过切换 GitHub 镜像上的分支轻松浏览 SDK 版本:android/platform_frameworks_base。
- 检查是否在最新版本的 Android 上发生,否则使用 blame 查看何时修复。
- 如果问题仍然存在,构建一个简单的复现案例。
- 在 b.android.com 上提交一个 issue,附带泄漏路径和复现案例。请记住在有新回复时跟进 issue。b/176886060 是一个有效且尊重的沟通的好例子。
- 在 LeakCanary 中创建一个 PR 来更新 AndroidReferenceMatchers。可选:如果您找到了在早期 Android 版本上清除该泄漏的技巧,请随意将其记录下来。
我如何知道 LeakCanary 正在运行?¶
您可以通过在 Logcat 中按 LeakCanary 标签过滤来确认 LeakCanary 是否正确启动
$ adb logcat | grep LeakCanary
D/LeakCanary: Installing AppWatcher
如果您在日志中没有看到 Installing AppWatcher
,请检查您的依赖项 (./gradlew app:dependencies
) 并确保 LeakCanary 在其中。
请注意,LeakCanary 在测试中会自动禁用(参见 LeakCanary 测试环境检测)
$ adb logcat | grep LeakCanary
D/LeakCanary: Installing AppWatcher
D/LeakCanary: JUnit detected in classpath, app is running tests => disabling heap dumping & analysis
D/LeakCanary: Updated LeakCanary.config: Config(dumpHeap=false)
LeakCanary 将堆转储文件存储在哪里?¶
默认行为是将堆转储文件存储在应用目录下的 leakcanary
文件夹中。如果应用已被授予 android.permission.WRITE_EXTERNAL_STORAGE
权限,则堆转储文件将存储在外部存储的 Download
文件夹下的 leakcanary-com.example
文件夹中(其中 com.example
是您的应用包名)。如果应用未被授予 android.permission.WRITE_EXTERNAL_STORAGE
权限但该权限已在 AndroidManifest.xml
中列出,则 LeakCanary 将显示一个通知,点击该通知即可授予权限。
我如何深入分析泄漏路径?¶
有时仅靠泄漏路径不够,您需要使用 MAT 或 YourKit 深入分析堆转储文件。
- 前往堆分析屏幕,点击溢出菜单,选择 分享堆转储文件。
以下是如何在堆转储文件中找到泄漏实例:
- 查找所有
leakcanary.KeyedWeakReference
实例。 - 对于每个实例,查看
key
字段。 - 找到
KeyedWeakReference
实例,其key
字段等于 LeakCanary 报告的引用键。 - 该
KeyedWeakReference
的referent
字段就是您泄漏的对象。 - 从那时起,问题就掌握在您手中了。一个好的开始是查看到 GC Roots 的最短路径(排除弱引用)。
为什么只需添加依赖项,LeakCanary 就能安装成功?¶
在 Android 上,Content Provider 在 Application 实例创建之后但在 Application.onCreate() 调用之前创建。leakcanary-object-watcher-android
artifact 在其 AndroidManifest.xml
文件中定义了一个非导出的 ContentProvider。当该 ContentProvider 安装后,它会为应用添加 Activity 和 Fragment 生命周期监听器。
LeakCanary 添加了多少方法?¶
0。LeakCanary 是一个仅用于调试的库。
如何使用 SNAPSHOT 版本?¶
将您的依赖项更新到最新的 SNAPSHOT 版本(参见 build.gradle)
dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:3.0-alpha-9-SNAPSHOT'
}
添加 Sonatype 的 snapshots
仓库
repositories {
mavenCentral()
maven {
url 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
}
}
LeakCanary 背后的开发者是谁?¶
LeakCanary 由 @pyricau 创建并开源,社区的 许多贡献者 也为此付出了努力。
它为什么叫 LeakCanary?¶
名称 LeakCanary 引用了谚语煤矿里的金丝雀,因为 LeakCanary 是一个用于通过提前预警危险来检测风险的哨兵。感谢 @edenman 提出这个名字!
是谁制作了 Logo?¶
- @pyricau 快速制作了 Logo 的第一个版本。它基于 Android Asset Studio 的剪贴画,并混合了金丝雀照片的选区。感叹号代表危险,盾牌代表保护,而鸟,嗯,就是金丝雀。
- @romainguy 将这个不太美观的 Logo 变成了一个漂亮的矢量图。
- @flickator 为 LeakCanary 2.0 设计了一个更漂亮的 Logo!