在 LeakCanary 泄漏跟踪中查找原因

Posted

技术标签:

【中文标题】在 LeakCanary 泄漏跟踪中查找原因【英文标题】:Finding cause in LeakCanary leak trace 【发布时间】:2020-06-05 10:40:05 【问题描述】:

LeakCanary 报告了我们的应用程序中的内存泄漏,并带有以下泄漏跟踪:

05-24 08:41:05.380044 16534 19408 D LeakCanary: HeapAnalysisSuccess(heapDumpFile=/data/user/0/..../files/leakcanary/2020-05-24_08-24-07_502.hprof, createdAtTimeMillis=1590334865374, analysisDurationMillis=85525, applicationLeaks=[ApplicationLeak(className=<>.media.MediaControlActivity, leakTrace=
05-24 08:41:05.380044 16534 19408 D LeakCanary: ┬
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ android.provider.FontsContract
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: NO (HomeApplication↓ is not leaking and a class is never leaking)
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    GC Root: System class
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ static FontsContract.sContext
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ <>.application.HomeApplication
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: NO (Application is a singleton)
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    HomeApplication does not wrap an activity context
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ HomeApplication.mLoadedApk
05-24 08:41:05.380044 16534 19408 D LeakCanary: │                      ~~~~~~~~~~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ android.app.LoadedApk
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ LoadedApk.mReceivers
05-24 08:41:05.380044 16534 19408 D LeakCanary: │                ~~~~~~~~~~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ android.util.ArrayMap
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ ArrayMap.mArray
05-24 08:41:05.380044 16534 19408 D LeakCanary: │               ~~~~~~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ java.lang.Object[]
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ array Object[].[9]
05-24 08:41:05.380044 16534 19408 D LeakCanary: │                     ~~~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ android.util.ArrayMap
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ ArrayMap.mArray
05-24 08:41:05.380044 16534 19408 D LeakCanary: │               ~~~~~~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ java.lang.Object[]
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ array Object[].[58]
05-24 08:41:05.380044 16534 19408 D LeakCanary: │                     ~~~~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ ayf
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ ayf.a
05-24 08:41:05.380044 16534 19408 D LeakCanary: │          ~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ ayg
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ ayg.b
05-24 08:41:05.380044 16534 19408 D LeakCanary: │          ~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ als
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ als.b
05-24 08:41:05.380044 16534 19408 D LeakCanary: │          ~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ alt
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ alt.b
05-24 08:41:05.380044 16534 19408 D LeakCanary: │          ~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ╰→ <>.media.MediaControlActivity
05-24 08:41:05.380044 16534 19408 D LeakCanary: ​     Leaking: YES (Activity#mDestroyed is true and ObjectWatcher was watching this)
05-24 08:41:05.380044 16534 19408 D LeakCanary: ​     key = 758a249e-d3c7-44e3-b633-4649a5574735
05-24 08:41:05.380044 16534 19408 D LeakCanary: ​     watchDurationMillis = 5397
05-24 08:41:05.380044 16534 19408 D LeakCanary: ​     retainedDurationMillis = 393
05-24 08:41:05.380044 16534 19408 D LeakCanary: , retainedHeapByteSize=43842), ApplicationLeak(className=aym, leakTrace=
05-24 08:41:05.380044 16534 19408 D LeakCanary: ┬

据我所知,原因在MediaControlActivity 的某个地方。另外,我看到正在存储的引用从 Application 类开始/

但我不明白这两者是如何联系起来的,因为跟踪中的某些行有点混淆,特别是这部分:

├─ java.lang.Object[]
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ array Object[].[58]
05-24 08:41:05.380044 16534 19408 D LeakCanary: │                     ~~~~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ ayf
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ ayf.a
05-24 08:41:05.380044 16534 19408 D LeakCanary: │          ~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ ayg
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ ayg.b
05-24 08:41:05.380044 16534 19408 D LeakCanary: │          ~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ als
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ als.b
05-24 08:41:05.380044 16534 19408 D LeakCanary: │          ~
05-24 08:41:05.380044 16534 19408 D LeakCanary: ├─ alt
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    Leaking: UNKNOWN
05-24 08:41:05.380044 16534 19408 D LeakCanary: │    ↓ alt.b
05-24 08:41:05.380044 16534 19408 D LeakCanary: │          ~

所以,我的问题是: - 为什么这里的痕迹被混淆了?是因为proguard吗?如果没有,还有什么?

【问题讨论】:

这在我集成 Glide 后开始发生,因此也添加了该标签。 【参考方案1】:

跟踪被混淆是因为代码被混淆了。如果您为该构建启用了 Proguard,则有一个插件可以帮助 LeakCanary:https://square.github.io/leakcanary/recipes/#using-leakcanary-with-obfuscated-apps

如果您没有启用 Proguard,那么很可能是因为您使用了一个被混淆的库。您应该尝试找出它是哪个库。

【讨论】:

是的,在我参考了映射文件后,原来是滑行问题。

以上是关于在 LeakCanary 泄漏跟踪中查找原因的主要内容,如果未能解决你的问题,请参考以下文章

了解 LeakCanary 内存泄漏堆栈跟踪

LeakCanary检测内存泄漏

Android内存泄漏检测LeakCanary使用总结

LeakCanary

Android内存泄漏查找和解决

LeakCanary检测内存泄漏.md