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

DataBinding + setLifecycleOwner + Stopped Fragment => Memory Leak? #1137

Closed
DeweyReed opened this issue Oct 25, 2018 · 8 comments
Closed

DataBinding + setLifecycleOwner + Stopped Fragment => Memory Leak? #1137

DeweyReed opened this issue Oct 25, 2018 · 8 comments

Comments

@DeweyReed
Copy link

DeweyReed commented Oct 25, 2018

I have a fragment using DataBinding and setLifecycleOwner to use LiveData. Then I replace that fragment with another fragment and LeakCanary tells me this:

picture

In xyz.aprildown.ohmymemoryleak:1.0:1.
* android.widget.FrameLayout has leaked:
* Toast$TN.mNextView
* ↳ LinearLayout.mContext
* ↳ MainActivity.mFragments
* ↳ FragmentController.mHost
* ↳ FragmentActivity$HostCallbacks.mFragmentManager
* ↳ FragmentManagerImpl.mActive
* ↳ SparseArray.mValues
* ↳ array Object[].[0]
* ↳ MainActivityFragment.!(mLifecycleRegistry)!
* ↳ LifecycleRegistry.!(mObserverMap)!
* ↳ FastSafeIterableMap.!(mEnd)!
* ↳ SafeIterableMap$Entry.!(mKey)!
* ↳ ViewDataBinding$OnStartListener.!(this$0)!
* ↳ FragmentMainBindingImpl.!(mboundView0)!
* ↳ FrameLayout

The leaked FrameLayout is the root view of the first fragment.

I created a simple repo to elaborate this and the full dumped info is also in its README.

It's probably from debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.2'.
The leak is not shown after I comment it.

Thanks in advance.

@natario1
Copy link

Seems to be LeakCanary leaking its own toast. Having the same issue. If I can provide more info let me know.

@lawloretienne
Copy link

@pyricau Is this still a known issue, and is it currently being worked on? Are we all getting false positives? Cuz i am seeing a similar leak where the Toast is at the top of the leak trace.

@jekopena
Copy link

I'm having exactly the same problem. I've tried removing DataBinding and still having a memory leak with small differences in the Canary Leak logs. Removed all Toasts from my application and still seeing this Toast$TN.mNextView at the beginning of the Leak Canary logs.

When I remove "debugImplementation "com.squareup.leakcanary:leakcanary-support-fragment:$leak_canary_version" from build.gradle I stop receiving this memory leak.

My app is very simple pet project, in case you want to take a look at my code the leaking fragment is in com.jekoding.notes.ui.noteslist.NotesListFragment:

Let me know if I can help with something.

@anthony-skr
Copy link

Hello,

I have exactly the same leaks (those which start with Toast$TN.mNextView).
I've struggled with them for few days, I finally I gave up... like impossible to find and fix.

So I think @natario1 is right: LeakCanary is leaking its own toast.

@pyricau
Copy link
Member

pyricau commented Nov 16, 2018

No, LeakCanar is not leaking its own toast. The root of a leak trace has nothing to do with the cause, the cause is something in there. More precisely, the cause is any one of elements with !.

So in this example:

In xyz.aprildown.ohmymemoryleak:1.0:1.
* android.widget.FrameLayout has leaked:
* Toast$TN.mNextView
* ↳ LinearLayout.mContext
* ↳ MainActivity.mFragments
* ↳ FragmentController.mHost
* ↳ FragmentActivity$HostCallbacks.mFragmentManager
* ↳ FragmentManagerImpl.mActive
* ↳ SparseArray.mValues
* ↳ array Object[].[0]
* ↳ MainActivityFragment.!(mLifecycleRegistry)!
* ↳ LifecycleRegistry.!(mObserverMap)!
* ↳ FastSafeIterableMap.!(mEnd)!
* ↳ SafeIterableMap$Entry.!(mKey)!
* ↳ ViewDataBinding$OnStartListener.!(this$0)!
* ↳ FragmentMainBindingImpl.!(mboundView0)!
* ↳ FrameLayout

The cause can only be one of these references:

* ↳ MainActivityFragment.!(mLifecycleRegistry)!
* ↳ LifecycleRegistry.!(mObserverMap)!
* ↳ FastSafeIterableMap.!(mEnd)!
* ↳ SafeIterableMap$Entry.!(mKey)!
* ↳ ViewDataBinding$OnStartListener.!(this$0)!
* ↳ FragmentMainBindingImpl.!(mboundView0)!

It sounds like MainActivityFragment is not destroyed, and the FrameLayout at the bottom is detached.

The way I read this: the first fragment uses data binding and a ViewDataBinding$OnStartListener for that first fragment view hierarchy was registered in the LifecycleRegistry that belongs to MainActivityFragment, and wasn't unregistered when the first fragment moved away.

@DeweyReed do you have a sample project? Or can you at least share the code of that first fragment / how it deals with with databinding?

@jekopena
Copy link

@pyricau , @DeweyReed said that he created a simple repo just to prove this error in https://github.com/DeweyReed/OhMyMemoryLeak

@pyricau
Copy link
Member

pyricau commented Nov 16, 2018

Oops, I should read better! Looking into it now.

@pyricau
Copy link
Member

pyricau commented Nov 16, 2018

Congrats everybody! You did find a memory leak in the data binding library.

I filed the details here: https://issuetracker.google.com/issues/119661177

The data binding team has been notified and they'll likely work on a fix relatively soon.

Thanks DeweyReed for the sample project, that helped a lot. I'm glad LeakCanary is helping make all of Android better :)

I'll close for now, there isn't much else to do on our end. We likely don't need to "exclude" this leak as it'll be fixed in the library itself, so no one will be stuck.

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

6 participants