LeakCanary has reported a memory leak in our app with following leak trace:
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: ┬
from this, I understand that the cause is somewhere in MediaControlActivity
. Also, I see that the reference being stored starts in the Application class/
But what I don't understand is how these two are linked, since some lines in the trace are kind of obfuscated, this part specifically:
├─ 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: │ ~
So, the questions that I have are: - why is the trace obfuscated here? Is is due to proguard? If not, what else?
The trace is obfuscated because the code is obfuscated. If you enabled Proguard for that build, there's a plugin to help LeakCanary: https://square.github.io/leakcanary/recipes/#using-leakcanary-with-obfuscated-apps
If you did not enable Proguard, then it's most likely because you use a library that has been obfuscated. You should try to figure out which library it is.