leakcanary
leakcanary copied to clipboard
Extend InputMethodManager workaround to API level 35
Example leak trace:
leakcanary.NoLeakAssertionFailedError: Application memory leaks were detected:
====================================
HEAP ANALYSIS RESULT
====================================
1 APPLICATION LEAKS
References underlined with "~~~" are likely causes.
Learn more at [https://squ.re/leaks](https://www.google.com/url?q=https://squ.re/leaks&sa=D).
44061 bytes retained by leaking objects
Signature: 4f5d3e652eeacb84138b7a40e62b473fe98037ce
┬───
│ GC Root: System class
│
├─ android.view.inputmethod.InputMethodManager class
│ Leaking: NO (InputMethodManager↓ is not leaking and a class is never leaking)
│ ↓ static InputMethodManager.sInstance
├─ android.view.inputmethod.InputMethodManager instance
│ Leaking: NO (InputMethodManager is a singleton)
│ ↓ InputMethodManager.mNextServedView
│ ~~~~~~~~~~~~~~~
├─ com.android.internal.policy.DecorView instance
│ Leaking: YES (View.mContext references a destroyed activity)
│ Retaining 44.1 kB in 683 objects
│ View not part of a window view hierarchy
│ View.mAttachInfo is null (view detached)
│ View.mWindowAttachCount = 1
│ mContext instance of com.android.internal.policy.DecorContext, wrapping activity androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity with mDestroyed = true
│ ↓ DecorView.mContentRoot
├─ android.widget.LinearLayout instance
│ Leaking: YES (DecorView↑ is leaking and View.mContext references a destroyed activity)
│ Retaining 2.3 kB in 23 objects
│ View is part of a window view hierarchy
│ View.mAttachInfo is null (view detached)
│ View.mWindowAttachCount = 1
│ mContext instance of androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity with mDestroyed = true
│ ↓ View.mContext
╰→ androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity instance
Leaking: YES (ObjectWatcher was watching this because androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity received Activity#onDestroy() callback and Activity#mDestroyed is true)
Retaining 3.0 kB in 40 objects
key = 2259ec5d-3313-40b0-bf3a-9b10cff01525
watchDurationMillis = 10407
retainedDurationMillis = 5406
mApplication instance of com.google.android.libraries.ads.mobile.maitier.testapps.genericapp.MainApplication
mBase instance of android.app.ContextImpl
====================================
0 LIBRARY LEAKS
A Library Leak is a leak caused by a known bug in 3rd party code that you do not have control over.
See [https://square.github.io/leakcanary/fundamentals-how-leakcanary-works/#4-categorizing-leaks](https://www.google.com/url?q=https://square.github.io/leakcanary/fundamentals-how-leakcanary-works/%234-categorizing-leaks&sa=D)
====================================
0 UNREACHABLE OBJECTS
An unreachable object is still in memory but LeakCanary could not find a strong reference path
from GC roots.
====================================
METADATA
Please include this in bug reports and Stack Overflow questions.
Build.VERSION.SDK_INT: 35
Build.MANUFACTURER: Google
LeakCanary version: v2.14
Class count: 36865
Instance count: 240339
Primitive array count: 177999
Object array count: 32355
Thread count: 62
Heap total bytes: 33628842
Bitmap count: 1
Bitmap total bytes: 1025
Large bitmap count: 0
Large bitmap total bytes: 0
Db 1: open /data/user/0/com.google.android.libraries.ads.mobile.maitier.testapps.genericapp/no_backup/androidx.work.workdb
Stats: LruCache[maxSize=3000,hits=128865,misses=223741,hitRate=36%] RandomAccess[bytes=11069875,reads=223741,travel=89466659815,range=40517377,size=50657186]
assertionTag: leakcanary
waitForRetainedDurationMillis: 5129
totalDurationMillis: 35168
Analysis duration: 21514 ms
Heap dump file path: /data/user/0/com.google.android.libraries.ads.mobile.maitier.testapps.genericapp/files/instrumentation_tests_2025-01-14_14-58-38_041.hprof
Heap dump timestamp: 1736895548072
Heap dump duration: 2510 ms
====================================
at leakcanary.NoLeakAssertionFailedError$Companion.throwOnApplicationLeaks$lambda$3(NoLeakAssertionFailedError.kt:25)
at leakcanary.NoLeakAssertionFailedError$Companion.$r8$lambda$YWXscVJi44IEBq_-uq5c_WHdK1k(Unknown Source:0)
at leakcanary.NoLeakAssertionFailedError$Companion$$ExternalSyntheticLambda0.reportHeapAnalysis(Unknown Source:0)
at leakcanary.AndroidDetectLeaksAssert.runLeakChecks(AndroidDetectLeaksAssert.kt:95)
at leakcanary.AndroidDetectLeaksAssert.assertNoLeaks(AndroidDetectLeaksAssert.kt:34)
at leakcanary.LeakAssertions.assertNoLeaks(LeakAssertions.kt:21)
at com.google.android.libraries.ads.mobile.maitier.MaitierLeakRule$apply$1.evaluate([MaitierLeakRule.kt:46](https://cs.corp.google.com/#search/&q=f:com/google/android/libraries/ads/mobile/maitier/MaitierLeakRule.kt:46&ws=jamesjliu/18240&snapshot=114))
at org.junit.rules.TestWatcher$1.evaluate([TestWatcher.java:61](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/rules/TestWatcher.java?q=evaluate&l=61&ws=jamesjliu/18240&snapshot=114))
at org.junit.rules.ExternalResource$1.evaluate([ExternalResource.java:54](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/rules/ExternalResource.java?q=evaluate&l=54&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner$3.evaluate([ParentRunner.java:308](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=evaluate&l=308&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate([BlockJUnit4ClassRunner.java:100](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/BlockJUnit4ClassRunner.java?q=evaluate&l=100&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner.runLeaf([ParentRunner.java:368](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=evaluate&l=368&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.BlockJUnit4ClassRunner.runChild([BlockJUnit4ClassRunner.java:103](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/BlockJUnit4ClassRunner.java?q=runLeaf&l=103&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.BlockJUnit4ClassRunner.runChild([BlockJUnit4ClassRunner.java:63](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/BlockJUnit4ClassRunner.java?q=runChild&l=63&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner$4.run([ParentRunner.java:333](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=runChild&l=333&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner$1.schedule([ParentRunner.java:81](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=run&l=81&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner.runChildren([ParentRunner.java:331](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=schedule&l=331&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner.-$$Nest$mrunChildren(Unknown Source:0)
at org.junit.runners.ParentRunner$2.evaluate([ParentRunner.java:295](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=runChildren&l=295&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner$3.evaluate([ParentRunner.java:308](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=evaluate&l=308&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner.run([ParentRunner.java:420](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=evaluate&l=420&ws=jamesjliu/18240&snapshot=114))
at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:162)
at org.junit.runners.Suite.runChild([Suite.java:128](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/Suite.java?l=128&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.Suite.runChild([Suite.java:27](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/Suite.java?q=runChild&l=27&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner$4.run([ParentRunner.java:333](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=runChild&l=333&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner$1.schedule([ParentRunner.java:81](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=run&l=81&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner.runChildren([ParentRunner.java:331](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=schedule&l=331&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner.-$$Nest$mrunChildren(Unknown Source:0)
at org.junit.runners.ParentRunner$2.evaluate([ParentRunner.java:295](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=runChildren&l=295&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner$3.evaluate([ParentRunner.java:308](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=evaluate&l=308&ws=jamesjliu/18240&snapshot=114))
at org.junit.runners.ParentRunner.run([ParentRunner.java:420](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runners/ParentRunner.java?q=evaluate&l=420&ws=jamesjliu/18240&snapshot=114))
at org.junit.runner.JUnitCore.run([JUnitCore.java:141](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runner/JUnitCore.java?q=run&l=141&ws=jamesjliu/18240&snapshot=114))
at org.junit.runner.JUnitCore.run([JUnitCore.java:119](https://cs.corp.google.com/piper///depot/google3/third_party/java_src/junit/main/java/org/junit/runner/JUnitCore.java?q=run&l=119&ws=jamesjliu/18240&snapshot=114))
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:68)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:467)
at android.app.Instrumentation$InstrumentationThread.run([Instrumentation.java:2594](https://cs.corp.google.com/#search/&q=f:android/app/Instrumentation.java))
@jjliu15 can you share a sample leaktrace on api 35?
@pyricau added to the description. I verified locally that this PR fixes the leak
Hi @pyricau, could you take another look? Thanks!