Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory Leak possibly due to no proper disposing of Composition #10

Open
Yash-Garg opened this issue Aug 12, 2022 · 1 comment
Open

Memory Leak possibly due to no proper disposing of Composition #10

Yash-Garg opened this issue Aug 12, 2022 · 1 comment

Comments

@Yash-Garg
Copy link

Yash-Garg commented Aug 12, 2022

I am facing a memory leak when using this library. I think it's probably due to the Composition used in bonsai/core/tree/Tree.kt.

There is a method for disposing the composition (composition.dispose()) which isn't getting called. It would be great if you can have a look at it.

Tried adding myComposeView.disposeComposition() in onStop() of Fragment, but got no luck.

Docs Reference

Leakcanary Stacktrace

D/LeakCanary:D/LeakCanary: ====================================
D/LeakCanary: HEAP ANALYSIS RESULT
D/LeakCanary: ====================================
D/LeakCanary: 3 APPLICATION LEAKS
D/LeakCanary:D/LeakCanary: References underlined with "~~~" are likely causes.
D/LeakCanary: Learn more at https://squ.re/leaks.
D/LeakCanary:D/LeakCanary: 2794 bytes retained by leaking objects
D/LeakCanary: Signature: 294c14f86ef1f535d2d18c00e3aefe49abd3e220
D/LeakCanary: ┬───
D/LeakCanary:GC Root: Input or output parameters in native code
D/LeakCanary:D/LeakCanary: ├─ dalvik.system.PathClassLoader instance
D/LeakCanary:Leaking: NO (SnapshotKtis not leaking and A ClassLoader is never leaking)
D/LeakCanary: │    ↓ ClassLoader.runtimeInternalObjects
D/LeakCanary: ├─ java.lang.Object[] array
D/LeakCanary:Leaking: NO (SnapshotKtis not leaking)
D/LeakCanary: │    ↓ Object[6667]
D/LeakCanary: ├─ androidx.compose.runtime.snapshots.SnapshotKt class
D/LeakCanary:Leaking: NO (Recomposeris not leaking and a class is never leaking)
D/LeakCanary: │    ↓ static SnapshotKt.applyObservers
D/LeakCanary: ├─ java.util.ArrayList instance
D/LeakCanary:Leaking: NO (Recomposeris not leaking)
D/LeakCanary: │    ↓ ArrayList[0]
D/LeakCanary: ├─ androidx.compose.runtime.Recomposer$recompositionRunner$2$unregisterApplyObserver$1 instance
D/LeakCanary:Leaking: NO (Recomposeris not leaking)
D/LeakCanary:Anonymous subclass of kotlin.jvm.internal.Lambda
D/LeakCanary: │    ↓ Recomposer$recompositionRunner$2$unregisterApplyObserver$1.this$0
D/LeakCanary: ├─ androidx.compose.runtime.Recomposer instance
D/LeakCanary:Leaking: NO (CompositionImplis not leaking and Recomposer is in state Idle)
D/LeakCanary: │    ↓ Recomposer.knownCompositions
D/LeakCanary: ├─ java.util.ArrayList instance
D/LeakCanary:Leaking: NO (CompositionImplis not leaking)
D/LeakCanary: │    ↓ ArrayList[0]
D/LeakCanary: ├─ androidx.compose.runtime.CompositionImpl instance
D/LeakCanary:Leaking: NO (Composition not disposed)
D/LeakCanary: │    ↓ CompositionImpl.composer
D/LeakCanary: │                      ~~~~~~~~
D/LeakCanary: ├─ androidx.compose.runtime.ComposerImpl instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 9.1 kB in 48 objects
D/LeakCanary: │    ↓ ComposerImpl.parentProvider
D/LeakCanary: │                   ~~~~~~~~~~~~~~
D/LeakCanary: ├─ androidx.compose.runtime.external.kotlinx.collections.immutable.implementations.immutableMap.PersistentHashMap
D/LeakCanary: │  instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 320 B in 8 objects
D/LeakCanary: │    ↓ PersistentHashMap.node
D/LeakCanary: │                        ~~~~
D/LeakCanary: ├─ androidx.compose.runtime.external.kotlinx.collections.immutable.implementations.immutableMap.TrieNode instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 296 B in 7 objects
D/LeakCanary: │    ↓ TrieNode.buffer
D/LeakCanary: │               ~~~~~~
D/LeakCanary: ├─ java.lang.Object[] array
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 272 B in 6 objects
D/LeakCanary: │    ↓ Object[45]
D/LeakCanary: │            ~~~~
D/LeakCanary: ├─ androidx.compose.runtime.StaticValueHolder instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 12 B in 1 objects
D/LeakCanary: │    ↓ StaticValueHolder.value
D/LeakCanary: │                        ~~~~~
D/LeakCanary: ├─ androidx.fragment.app.FragmentViewLifecycleOwner instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 173 B in 6 objects
D/LeakCanary: │    ↓ FragmentViewLifecycleOwner.mFragment
D/LeakCanary: │                                 ~~~~~~~~~
D/LeakCanary: ╰→ dev.yashgarg.qbit.ui.torrent.tabs.TorrentFilesFragment instance
D/LeakCanary:Leaking: YES (ObjectWatcher was watching this because dev.yashgarg.qbit.ui.torrent.tabs.TorrentFilesFragment
D/LeakCanary: ​     received Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
D/LeakCanary:Retaining 2.8 kB in 105 objects
D/LeakCanary: ​     key = 729161f9-e2c4-4211-a526-d0a54992cd9e
D/LeakCanary: ​     watchDurationMillis = 5484
D/LeakCanary: ​     retainedDurationMillis = 483
D/LeakCanary:D/LeakCanary: 210 bytes retained by leaking objects
D/LeakCanary: Signature: cd1c7c9324750e1908bfb93e73a7daaccc8ddf30
D/LeakCanary: ┬───
D/LeakCanary:GC Root: Input or output parameters in native code
D/LeakCanary:D/LeakCanary: ├─ dalvik.system.PathClassLoader instance
D/LeakCanary:Leaking: NO (SnapshotKtis not leaking and A ClassLoader is never leaking)
D/LeakCanary: │    ↓ ClassLoader.runtimeInternalObjects
D/LeakCanary: ├─ java.lang.Object[] array
D/LeakCanary:Leaking: NO (SnapshotKtis not leaking)
D/LeakCanary: │    ↓ Object[6667]
D/LeakCanary: ├─ androidx.compose.runtime.snapshots.SnapshotKt class
D/LeakCanary:Leaking: NO (Recomposeris not leaking and a class is never leaking)
D/LeakCanary: │    ↓ static SnapshotKt.applyObservers
D/LeakCanary: ├─ java.util.ArrayList instance
D/LeakCanary:Leaking: NO (Recomposeris not leaking)
D/LeakCanary: │    ↓ ArrayList[0]
D/LeakCanary: ├─ androidx.compose.runtime.Recomposer$recompositionRunner$2$unregisterApplyObserver$1 instance
D/LeakCanary:Leaking: NO (Recomposeris not leaking)
D/LeakCanary:Anonymous subclass of kotlin.jvm.internal.Lambda
D/LeakCanary: │    ↓ Recomposer$recompositionRunner$2$unregisterApplyObserver$1.this$0
D/LeakCanary: ├─ androidx.compose.runtime.Recomposer instance
D/LeakCanary:Leaking: NO (CompositionImplis not leaking and Recomposer is in state Idle)
D/LeakCanary: │    ↓ Recomposer.knownCompositions
D/LeakCanary: ├─ java.util.ArrayList instance
D/LeakCanary:Leaking: NO (CompositionImplis not leaking)
D/LeakCanary: │    ↓ ArrayList[0]
D/LeakCanary: ├─ androidx.compose.runtime.CompositionImpl instance
D/LeakCanary:Leaking: NO (Composition not disposed)
D/LeakCanary: │    ↓ CompositionImpl.slotTable
D/LeakCanary: │                      ~~~~~~~~~
D/LeakCanary: ├─ androidx.compose.runtime.SlotTable instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 345 B in 17 objects
D/LeakCanary: │    ↓ SlotTable.slots
D/LeakCanary: │                ~~~~~
D/LeakCanary: ├─ java.lang.Object[] array
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 6.4 kB in 206 objects
D/LeakCanary: │    ↓ Object[32]
D/LeakCanary: │            ~~~~
D/LeakCanary: ├─ androidx.compose.ui.platform.DisposableSaveableStateRegistry instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 37 B in 2 objects
D/LeakCanary: │    ↓ DisposableSaveableStateRegistry.onDispose
D/LeakCanary: │                                      ~~~~~~~~~
D/LeakCanary: ├─ androidx.compose.ui.platform.DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$1 instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 21 B in 1 objects
D/LeakCanary:Anonymous subclass of kotlin.jvm.internal.Lambda
D/LeakCanary: │    ↓ DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$1.$androidxRegistry
D/LeakCanary: │                                                                                  ~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ androidx.savedstate.SavedStateRegistry instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 506 B in 19 objects
D/LeakCanary: │    ↓ SavedStateRegistry.components
D/LeakCanary: │                         ~~~~~~~~~~
D/LeakCanary: ├─ androidx.arch.core.internal.SafeIterableMap instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 483 B in 18 objects
D/LeakCanary: │    ↓ SafeIterableMap["androidx.lifecycle.internal.SavedStateHandlesProvider"]
D/LeakCanary: │                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ androidx.lifecycle.SavedStateHandlesProvider instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 251 B in 10 objects
D/LeakCanary: │    ↓ SavedStateHandlesProvider.viewModel$delegate
D/LeakCanary: │                                ~~~~~~~~~~~~~~~~~~
D/LeakCanary: ├─ kotlin.SynchronizedLazyImpl instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 230 B in 9 objects
D/LeakCanary: │    ↓ SynchronizedLazyImpl._value
D/LeakCanary: │                           ~~~~~~
D/LeakCanary: ╰→ androidx.lifecycle.SavedStateHandlesVM instance
D/LeakCanary:Leaking: YES (ObjectWatcher was watching this because androidx.lifecycle.SavedStateHandlesVM received
D/LeakCanary:ViewModel#onCleared() callback)
D/LeakCanary:Retaining 210 B in 8 objects
D/LeakCanary: ​     key = 375b335d-00db-4565-8c6d-0848ea7ca599
D/LeakCanary: ​     watchDurationMillis = 5485
D/LeakCanary: ​     retainedDurationMillis = 483
D/LeakCanary:D/LeakCanary: 15324 bytes retained by leaking objects
D/LeakCanary: Signature: 3074046c89ba82b393e6e7ba1f02c8a330683dbd
D/LeakCanary: ┬───
D/LeakCanary:GC Root: Input or output parameters in native code
D/LeakCanary:D/LeakCanary: ├─ dalvik.system.PathClassLoader instance
D/LeakCanary:Leaking: NO (SnapshotKtis not leaking and A ClassLoader is never leaking)
D/LeakCanary: │    ↓ ClassLoader.runtimeInternalObjects
D/LeakCanary: ├─ java.lang.Object[] array
D/LeakCanary:Leaking: NO (SnapshotKtis not leaking)
D/LeakCanary: │    ↓ Object[6667]
D/LeakCanary: ├─ androidx.compose.runtime.snapshots.SnapshotKt class
D/LeakCanary:Leaking: NO (Recomposeris not leaking and a class is never leaking)
D/LeakCanary: │    ↓ static SnapshotKt.applyObservers
D/LeakCanary: ├─ java.util.ArrayList instance
D/LeakCanary:Leaking: NO (Recomposeris not leaking)
D/LeakCanary: │    ↓ ArrayList[0]
D/LeakCanary: ├─ androidx.compose.runtime.Recomposer$recompositionRunner$2$unregisterApplyObserver$1 instance
D/LeakCanary:Leaking: NO (Recomposeris not leaking)
D/LeakCanary:Anonymous subclass of kotlin.jvm.internal.Lambda
D/LeakCanary: │    ↓ Recomposer$recompositionRunner$2$unregisterApplyObserver$1.this$0
D/LeakCanary: ├─ androidx.compose.runtime.Recomposer instance
D/LeakCanary:Leaking: NO (CompositionImplis not leaking and Recomposer is in state Idle)
D/LeakCanary: │    ↓ Recomposer.knownCompositions
D/LeakCanary: ├─ java.util.ArrayList instance
D/LeakCanary:Leaking: NO (CompositionImplis not leaking)
D/LeakCanary: │    ↓ ArrayList[0]
D/LeakCanary: ├─ androidx.compose.runtime.CompositionImpl instance
D/LeakCanary:Leaking: NO (Composition not disposed)
D/LeakCanary: │    ↓ CompositionImpl.parent
D/LeakCanary: │                      ~~~~~~
D/LeakCanary: ├─ androidx.compose.runtime.ComposerImpl$CompositionContextImpl instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 190 B in 6 objects
D/LeakCanary: │    ↓ ComposerImpl$CompositionContextImpl.this$0
D/LeakCanary: │                                          ~~~~~~
D/LeakCanary: ├─ androidx.compose.runtime.ComposerImpl instance
D/LeakCanary:Leaking: UNKNOWN
D/LeakCanary:Retaining 17.2 kB in 54 objects
D/LeakCanary: │    ↓ ComposerImpl.composition
D/LeakCanary: │                   ~~~~~~~~~~~
D/LeakCanary: ├─ androidx.compose.runtime.CompositionImpl instance
D/LeakCanary:Leaking: YES (Composition disposed)
D/LeakCanary:Retaining 15.3 kB in 388 objects
D/LeakCanary: │    ↓ CompositionImpl.observations
D/LeakCanary: ├─ androidx.compose.runtime.collection.IdentityScopeMap instance
D/LeakCanary:Leaking: YES (CompositionImplis leaking)
D/LeakCanary:Retaining 13.2 kB in 356 objects
D/LeakCanary: │    ↓ IdentityScopeMap.scopeSets
D/LeakCanary: ├─ androidx.compose.runtime.collection.IdentityArraySet[] array
D/LeakCanary:Leaking: YES (CompositionImplis leaking)
D/LeakCanary:Retaining 10.5 kB in 252 objects
D/LeakCanary: │    ↓ IdentityArraySet[4]
D/LeakCanary: ├─ androidx.compose.runtime.collection.IdentityArraySet instance
D/LeakCanary:Leaking: YES (CompositionImplis leaking)
D/LeakCanary:Retaining 148 B in 5 objects
D/LeakCanary: │    ↓ IdentityArraySet.values
D/LeakCanary: ├─ java.lang.Object[] array
D/LeakCanary:Leaking: YES (CompositionImplis leaking)
D/LeakCanary:Retaining 132 B in 4 objects
D/LeakCanary: │    ↓ Object[0]
D/LeakCanary: ├─ androidx.compose.runtime.RecomposeScopeImpl instance
D/LeakCanary:Leaking: YES (CompositionImplis leaking)
D/LeakCanary:Retaining 68 B in 3 objects
D/LeakCanary: │    ↓ RecomposeScopeImpl.block
D/LeakCanary: ├─ androidx.compose.ui.platform.ComposeView$Content$1 instance
D/LeakCanary:Leaking: YES (CompositionImplis leaking)
D/LeakCanary:Retaining 20 B in 1 objects
D/LeakCanary:Anonymous subclass of kotlin.jvm.internal.Lambda
D/LeakCanary: │    ↓ ComposeView$Content$1.$tmp1_rcvr
D/LeakCanary: ╰→ androidx.compose.ui.platform.ComposeView instance
D/LeakCanary:Leaking: YES (ObjectWatcher was watching this because dev.yashgarg.qbit.ui.torrent.tabs.TorrentFilesFragment
D/LeakCanary: ​     received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks))
D/LeakCanary:Retaining 2.4 kB in 39 objects
D/LeakCanary: ​     key = d15cfab8-cfee-4de6-82f2-9e5e4d4f6d02
D/LeakCanary: ​     watchDurationMillis = 5489
D/LeakCanary: ​     retainedDurationMillis = 488
D/LeakCanary:View not part of a window view hierarchy
D/LeakCanary:View.mAttachInfo is null (view detached)
D/LeakCanary:View.mID = R.id.filesComposeView
D/LeakCanary:View.mWindowAttachCount = 1
D/LeakCanary: ​     mContext instance of dev.yashgarg.qbit.MainActivity with mDestroyed = false
D/LeakCanary: ====================================
@Yash-Garg Yash-Garg changed the title Memory Leak possibly due to not proper dispose of Composition Memory Leak possibly due to no disposition of Composition Aug 12, 2022
@Yash-Garg Yash-Garg changed the title Memory Leak possibly due to no disposition of Composition Memory Leak possibly due to no proper disposing of Composition Aug 12, 2022
@Yash-Garg Yash-Garg reopened this Aug 12, 2022
@foodpoison
Copy link

Hi I'm encountering memory leak of this library as well, do you need help fixing this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants