[Snackbar] Memory leak due to setAnchorView
See original GitHub issueDescription: Anchoring works as expected but, the listener is never removed and LeakCanary is getting a memory leak
Expected behavior: Itβs working as expected, SnackBar is shown above the desired view. But there is a Memory leak, I tried referencing via IdRes, view from ViewBinding, view from findViewById, always the same. When I remove setAnchroView there is no leak.
I think itβs connected with ViewUtils.addOnGlobalLayoutListener
in setAnchorView function of BaseTransientBottomBar, its never removed after showing
Source code:
with(viewBinding.venueRecyclerView) {
Snackbar
.make(
viewBinding.root,
context.getString(R.string.tap_again_in_map_venue),
Snackbar.LENGTH_SHORT
)
.setAnchorView(this)
.show()
}
Leak canary :
β¬βββ
β 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 (DecorViewβ is not leaking and InputMethodManager is a singleton)
β β InputMethodManager.mCurRootView
ββ com.android.internal.policy.DecorView instance
β Leaking: NO (View attached)
β View is part of a window view hierarchy
β View.mAttachInfo is not null (view attached)
β View.mWindowAttachCount = 1
β mContext instance of com.android.internal.policy.DecorContext, wrapping activity com.upgrades.venue.user.
β presentation.MainActivity with mDestroyed = false
β β View.mAttachInfo
β ~~~~~~~~~~~
ββ android.view.View$AttachInfo instance
β Leaking: UNKNOWN
β Retaining 2.4 MB in 13380 objects
β β View$AttachInfo.mTreeObserver
β ~~~~~~~~~~~~~
ββ android.view.ViewTreeObserver instance
β Leaking: UNKNOWN
β Retaining 2.4 MB in 13337 objects
β β ViewTreeObserver.mOnGlobalLayoutListeners
β ~~~~~~~~~~~~~~~~~~~~~~~~
ββ android.view.ViewTreeObserver$CopyOnWriteArray instance
β Leaking: UNKNOWN
β Retaining 2.1 MB in 13264 objects
β β ViewTreeObserver$CopyOnWriteArray.mData
β ~~~~~
ββ java.util.ArrayList instance
β Leaking: UNKNOWN
β Retaining 2.1 MB in 13262 objects
β β ArrayList.elementData
β ~~~~~~~~~~~
ββ java.lang.Object[] array
β Leaking: UNKNOWN
β Retaining 2.1 MB in 13261 objects
β β Object[].[0]
β ~~~
ββ com.google.android.material.snackbar.BaseTransientBottomBar$2 instance
β Leaking: UNKNOWN
β Retaining 2.1 MB in 13260 objects
β Anonymous class implementing android.view.ViewTreeObserver$OnGlobalLayoutListener
β β BaseTransientBottomBar$2.this$0
β ~~~~~~
ββ com.google.android.material.snackbar.Snackbar instance
β Leaking: UNKNOWN
β Retaining 2.1 MB in 13259 objects
β context instance of com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
β β BaseTransientBottomBar.anchorView
β ~~~~~~~~~~
ββ androidx.recyclerview.widget.RecyclerView instance
β Leaking: UNKNOWN
β Retaining 2.1 MB in 13011 objects
β View not part of a window view hierarchy
β View.mAttachInfo is null (view detached)
β View.mID = R.id.venue_recycler_view
β View.mWindowAttachCount = 1
β mContext instance of dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper, wrapping
β activity com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
β β View.mContext
β ~~~~~~~~
ββ dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper instance
β Leaking: UNKNOWN
β Retaining 172 B in 6 objects
β mBase instance of com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
β ViewComponentManager$FragmentContextWrapper wraps an Activity with Activity.mDestroyed false
β β ViewComponentManager$FragmentContextWrapper.fragment
β ~~~~~~~~
β°β com.upgrades.venue.user.presentation.explore.ExploreMapFragment instance
β Leaking: YES (ObjectWatcher was watching this because com.upgrades.venue.user.presentation.explore.
β ExploreMapFragment received Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
β Retaining 1.9 MB in 10078 objects
β key = 90d80d2a-9c93-4a64-960a-5925009d3547
β watchDurationMillis = 199061
β retainedDurationMillis = 194060
β componentContext instance of dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper,
β wrapping activity com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
β uiController instance of com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
2807 bytes retained by leaking objects
Signature: e3e5b03a4f9b45443e8991fe4237eb4ebee6defa
Android API version: Any
Material Library version: Material Android Library version 1.3.0-rc01
Device: 2 emulators Pixel 2 and Pixel C, and Huawei mate 20 lite
Issue Analytics
- State:
- Created 3 years ago
- Reactions:9
- Comments:7 (1 by maintainers)
Top Results From Across the Web
Memory Leak due to Snackbar - Stack Overflow
IΒ΄m creating a Snackbar in the onCreateView and set it to null in onDestroyView . However I get a memory leak every time...
Read more >Preventing and detecting memory leaks in Android apps
Memory leaks can cause your Android app to crash, causing frustration and lower usage. Learn how to fix them in this guide.
Read more >Memory Leak Due To Snackbar - ADocLib
A Snackbar is a widget that looks like a small banner that pops up at the bottom ... 1 ListView and GridView's item...
Read more >Memory Leaks in Android: Find, Fix, and Avoid
1. You should not: Avoid using static variables for views or context-related references. Pass a context-related reference to a Singleton class. Improperly use...
Read more >[Snackbar] setAnchorView() for BottomNavigationView does ...
setAnchorView () to show the Snackbar above the BottomNavigationView. However, Snackbar does ... Possible memory leak in 2.1.210, 5, 2022-04-02, 2022-09-29.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The issue has been fixed for most of the cases except for one - when the snackbar is still showing but the anchor view is detached. We are figuring out a more comprehensive fix here.
We hit this issue and worked around it by keeping a reference to the
Snackbar
and setting theanchorView
back tonull
when our ActivityβsonDestroy()
is called. This removes theOnGlobalLayoutListener
for the original anchorView and removes the leak.Looking at the code for setAnchorView() you can see that it first removes the existing
OnGlobalLayoutListener
and then adds a new one. However, because we call it withnull
, a new one doesnβt get added as thereβs a null check inViewUtils.addOnGlobalLayoutListener()