As discussed in here, this is another leak of EditText(or any other subclass of it) that does not get destroyed every time it gets focused and retains the mContext until the focus gets shifted to another EditText. Please note that mContext is destroyed as soon as the focus gets shifted to another EditText and again a new mContext is retained.
Let me know if more info needed.
Leak trace generated on API 23 LG Nexus 5 although when tested on higher versions the leak is gone.
Steps to reproduce: Simple just use an EditText anywhere inside activity and make sure it's focused and after Activity.onDestroy() you will get the leak.
ApplicationLeak(className=com.colevit.furmate.module.container.ContainerActivity, leakTrace=
┬
├─ java.lang.Thread
│ Leaking: UNKNOWN
│ Thread name: 'Studio:InputCon'
│ GC Root: Java local variable
│ ↓ thread Thread.<Java Local>
│ ~~~~~~~~~~~~
├─ com.android.tools.profiler.support.event.InputConnectionWrapper
│ Leaking: UNKNOWN
│ ↓ InputConnectionWrapper.mTarget
│ ~~~~~~~
├─ com.android.internal.widget.EditableInputConnection
│ Leaking: UNKNOWN
│ ↓ EditableInputConnection.mTargetView
│ ~~~~~~~~~~~
├─ androidx.appcompat.widget.AppCompatEditText
│ Leaking: YES (View.mContext references a destroyed activity)
│ mContext instance of android.view.ContextThemeWrapper, wrapping activity com.colevit.furmate.module.container.ContainerActivity with mDestroyed = true
│ View#mParent is set
│ View#mAttachInfo is null (view detached)
│ View.mWindowAttachCount = 1
│ ↓ AppCompatEditText.mContext
├─ android.view.ContextThemeWrapper
│ Leaking: YES (AppCompatEditText↑ is leaking and ContextThemeWrapper wraps an Activity with Activity.mDestroyed true)
│ ↓ ContextThemeWrapper.mBase
╰→ com.colevit.furmate.module.container.ContainerActivity
Leaking: YES (ContextThemeWrapper↑ is leaking and Activity#mDestroyed is true and ObjectWatcher was watching this)
key = 618d2116-4c2d-4118-ab3a-a9b5d6f8ae68
watchDurationMillis = 7833
retainedDurationMillis = 2833
, retainedHeapByteSize=7447)
🙏Thank you for opening an issue! LeakCanary is maintained by volunteers from the community. Please be kind and remember that LeakCanary isn't anyone's main job 😘.
com.android.tools.profiler.support.event.InputConnectionWrapper
So it's only happening when the debugger/profiler/whatever is attached and doesn't happen i production, right?
LeakCanary as of v2.0+ can only be used as a debugImplementation in gradle and is not installed in release artifacts. Thats why you may not see these logs in production but that doesn't mean the leak is gone, if this is what you mean.
com.android.tools.profiler.support.event.InputConnectionWrapper
So it's only happening when the debugger/profiler/whatever is attached and doesn't happen i production, right?
LeakCanary as of v2.0+ can only be used as a debugImplementation in gradle
Recently a popular app decided implementation is fine and included LeakCanary in production. So no, LeakCanary can be included wherever you want and nothing is going to stop you.
My point is that
Thread name: 'Studio:InputCon'
com.android.tools.profiler.support.event.InputConnectionWrapper
sounds like it's connected to Android Studio. That wouldn't be a concern in production.
This definitely is a library/Android SDK leak, I'm just pitching information for the leak description.
@consp1racy Then I would say I must test its release version as well before commenting on that.
In the mean time I want to mention a similar leak I found while I was recreating this leak. I hope that both the leaks are same but differs in traces due to some reason, what's remarkable is that _the other one is already an identified leak by LeakCanary._ Check this out.
That's a totally different leak, just follow the trace. C'mon, if LeakCanary says it's a different leak then it is a different leak. Have some trust, it's the tool's job, it's been doing that for years.
That's a totally different leak, just follow the trace. C'mon, if LeakCanary says it's a different leak then it is a different leak. Have some trust, it's the tool's job, it's been doing that for years.
Yeah, obviously I trust LeakCanary that's why I use it. But what makes me doubtful is that how could a leak can disappear in a similar implementation with same config. If you see, these two leaks are different but the one disappears in the other implementation.
Anyways @consp1racy this issue doesn't seem to comply with what you said and I neither find anything good with your statement in the official LeakCanary documentation as well.
LeakCanary as of v2.0+ can only be used as a debugImplementation in gradle
Recently a popular app decided
implementationis fine and included LeakCanary in production. So no, LeakCanary _can_ be included wherever you want and nothing is going to stop you.
@consp1racy Then I would say I must test its release version as well before commenting on that.
And not just the concerned one but as per my test LeakCanary is not able to trace any single leak in my release builds! This includes the one I mentioned earlier.
A few notes:
Thanks @pyricau for your points they are always helpful.
- LeakCanary displays just one path, there could be another path from a different root. However thread locals have power priority so its likely this leak is indeed caused by the profiler. We'd need a hprof file reproducing this to confirm.
I can share the hprof if that could help.
- While you def won't have the profiler in release builds and therefore this leak is debug only, might still be nice to identify the root cause and get it fixed so that we get less noise in leak reports.
And Yup, I tested the release build with AppWatcher enabled and the leak was gone. I did it as I thought if there is another path for the leak I can see with profiler disabled but that was not the case.
The last thing I am still wondering is that how is it possible for a library leak to go away in one project and present in the other?(I tested this with same configs and same device in release build and the library leak is present as expected)
This isn't the same leak. Here the problem most likely comes from com.android.tools.profiler.support.event.InputConnectionWrapper, sounds like maybe you used the profiler?
This isn't the same leak. Here the problem most likely comes from
com.android.tools.profiler.support.event.InputConnectionWrapper, sounds like maybe you used the profiler?
I think you got me wrong. Let me clarify.
Tell me if I am wrong?
Sorry, I'm confused, I don't really follow. The leak trace you shared at the top is related to the profiler. Are you saying its not?
No, you are absolutely right!
I am saying that in addition to this one there must be 1 more leak, how could the other go away after all thats a library leak? Is that possible? I am just asking if you don't mind!
I'm really sorry but I'm completely lost. You initially shared a single leak, which was classified as Application Leak. I don't understand which one is "the other one", how it's a library leak and what it has to do with the profiler leak.
Just look at the trace here and compare it with the above one. Even though these two are completely different, you will find few points common:
AppCompatEditText.While the leak trace here is an application leak and only exists in non prod, the other (I just referred above) is a library leak.
My question is why both the leaks can't be found at the same leak trace?
I am pointing this out because reproducing these two leaks has the same steps.
Thanks! I understand now.
A few things to consider:
Here the leaktraces are fairly different so this is probably two distinct bugs (or it could be some more general issue with InputMethodManager).
Ok, thanks for all of your points.
Your first point hit me so well that I just tested my app one more time exactly the same way I tested this and I found that the other(referred) leak is still there and I was not able to see it earlier was all because of the lifecycle of the application as you mentioned as _this one only occurs when you exit your application, not necessarily when Activity.onDestroy is called_.
Conclusion: Do not suppose that a leak is gone if it's not found. There could be another way/path to that.
This definitely is a library/Android SDK leak, I'm just pitching information for the leak description.
For the description I would add that InputConnectionWrapper holds EditableInputConnection.mTarget and hence the mContext only until a new view asks for keyboard input
I've created a repo where you can easily reproduce this leak on Samsung devices: https://github.com/dmytroKarataiev/TextInputLayout-MemoryLeak
Most helpful comment
I've created a repo where you can easily reproduce this leak on Samsung devices: https://github.com/dmytroKarataiev/TextInputLayout-MemoryLeak