LeakCanary – Leaks with SnapshotStateObserver and NavBackStackEntry in a Compose App

  Kiến thức lập trình

I’m using the Compose Navigation component in an app, but have some leaks appearing in LeakCanary when changing the mode on the phone (light to dark or vice-versa).

Find below the leak trace:

┬───
│ GC Root: Input or output parameters in native code
│
├─ dalvik.system.PathClassLoader instance
│    Leaking: NO (SnapshotKt↓ is not leaking and A ClassLoader is never leaking)
│    ↓ ClassLoader.runtimeInternalObjects
├─ java.lang.Object[] array
│    Leaking: NO (SnapshotKt↓ is not leaking)
│    ↓ Object[173]
├─ androidx.compose.runtime.snapshots.SnapshotKt class
│    Leaking: NO (a class is never leaking)
│    ↓ static SnapshotKt.applyObservers
│                        ~~~~~~~~~~~~~~
├─ java.util.ArrayList instance
│    Leaking: UNKNOWN
│    Retaining 19,0 MB in 8217 objects
│    ↓ ArrayList[0]
│               ~~~
├─ androidx.compose.runtime.snapshots.SnapshotStateObserver$applyObserver$1
│  instance
│    Leaking: UNKNOWN
│    Retaining 19,0 MB in 8190 objects
│    Anonymous subclass of kotlin.jvm.internal.Lambda
│    ↓ SnapshotStateObserver$applyObserver$1.this$0
│                                            ~~~~~~
├─ androidx.compose.runtime.snapshots.SnapshotStateObserver instance
│    Leaking: UNKNOWN
│    Retaining 19,0 MB in 8189 objects
│    ↓ SnapshotStateObserver.observedScopeMaps
│                            ~~~~~~~~~~~~~~~~~
├─ androidx.compose.runtime.collection.MutableVector instance
│    Leaking: UNKNOWN
│    Retaining 19,0 MB in 8185 objects
│    ↓ MutableVector.content
│                    ~~~~~~~
├─ androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap[]
│  array
│    Leaking: UNKNOWN
│    Retaining 19,0 MB in 8184 objects
│    ↓ SnapshotStateObserver$ObservedScopeMap[0]
│                                            ~~~
├─ androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap
│  instance
│    Leaking: UNKNOWN
│    Retaining 19,0 MB in 8183 objects
│    ↓ SnapshotStateObserver$ObservedScopeMap.scopeToValues
│                                             ~~~~~~~~~~~~~
├─ androidx.collection.MutableScatterMap instance
│    Leaking: UNKNOWN
│    Retaining 208 B in 8 objects
│    ↓ ScatterMap.keys
│                 ~~~~
├─ java.lang.Object[] array
│    Leaking: UNKNOWN
│    Retaining 28 B in 1 objects
│    ↓ Object[0]
│            ~~~
├─ androidx.compose.animation.core.SeekableTransitionState instance
│    Leaking: UNKNOWN
│    Retaining 772 B in 28 objects
│    ↓ SeekableTransitionState.composedTargetState
│                              ~~~~~~~~~~~~~~~~~~~
├─ androidx.navigation.NavBackStackEntry instance
│    Leaking: UNKNOWN
│    Retaining 19,0 MB in 8068 objects
│    context instance of com.my_package.my_app.ui.container.MainActivity with
│    mDestroyed = true
│    ↓ NavBackStackEntry.context
│                        ~~~~~~~
╰→ com.my_package.my_app.ui.container.MainActivity instance
​     Leaking: YES (ObjectWatcher was watching this because com.my_package.my_app.ui.container.MainActivity received Activity#onDestroy() callback
​     and Activity#mDestroyed is true)
​     Retaining 18,8 MB in 4084 objects
​     key = be3c9a4a-5aed-454e-830a-53bfe384047d
​     watchDurationMillis = 35047
​     retainedDurationMillis = 30045
​     mApplication instance of com.my_package.my_app.SingletonApp
​     mBase instance of android.app.ContextImpl

METADATA

Build.VERSION.SDK_INT: 31
Build.MANUFACTURER: samsung
LeakCanary version: 3.0-alpha-1
App process name: com.my_package.my_app
Class count: 27875
Instance count: 257685
Primitive array count: 170044
Object array count: 32858
Thread count: 39
Heap total bytes: 42026057
Bitmap count: 6
Bitmap total bytes: 37316166
Large bitmap count: 0
Large bitmap total bytes: 0
Db 1: open /data/user/0/com.my_package.my_app/databases/com.google.android.
datatransport.events
Stats: LruCache[maxSize=3000,hits=133209,misses=239547,hitRate=35%]
RandomAccess[bytes=11691281,reads=239547,travel=75185575277,range=38173124,size=
57603755]
Analysis duration: 34257 ms

Please, anyone have an idea on what’s going wrong?

Device used:

Samsung Galaxy S10 with Android 12

Settings:

Android Studio –> Jellyfish | 2023.3.1 RC

SDK Build-Tools –> 34.0.0

AGP –> 8.4.0-rc02

Kotlin –> 1.9.23

Compose –> BOM 2024.04.00 | Compiler 1.5.11

Dagger –> 2.51.1

Min SDK –> 26

Compile SDK –> 34

Target SDK –> 34

LEAVE A COMMENT