Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
212 views
in Technique[技术] by (71.8m points)

android - Could Navigation Arch Component create a false positive memory leak?

I have a basic knowledge of memory leaks and what can cause them. That's why I don't understand if I have a problem in my code or is it a false positive. I don't know which part of the code I should share since the project is not small. But just let me know in the comments and I will add required code.

I use navigation arch component and follow MVVM pattern. I added LeakCanary library later in the development of project and it immediately started to give me warnings about retained instances when I navigate between screens.

The problem occurs when I add fragments to the back stack. With each added fragment to the back stack the counter of retained instances increases. When it reaches the threshold value of 5 LeakCanary dumps the heap and provides report.

But if I click on back button and return to previous screens then counter of retained instances decreases and eventually, when returned to 1st screen all retained instances disappear.

If I look at heap analysis reports it says that the variable coordinatorLayout which is a reference to the CoordinatorLayout in xml has leaked. If I remove the variable and all of its usage and run the app again I see the same problem, but now with another variable that is a reference to another view in xml. I tried to remove all of the views and their usage that LeakCanary reported as leaking. When it said that a TextView, which is just used to set a text in onViewCreated and not used anywhere else, is leaking I started to doubt that there is a problem in my code.

I analyzed the lifecycle method calls in fragments and noticed that when I navigate to new screen for previous fragment all methods till and including onDestroyView gets called but not onDestroy. When I click back onDestroy is called for fragment that was on top of back stack and retained instances counter decreases.

I suspect that Navigation component is keeping the instance of a fragment when it is in back stack and LeakCanary is seeing it as a leak.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

That's how Fragments on the back stack work (and Navigation just uses the existing Fragment APIs): the Fragment's view is destroyed, but the Fragment itself is not destroyed - they are kept in the CREATED state until you hit the back button and return to the Fragment (after which onCreateView() will be called again and you'll move back up to RESUMED).

As per the Fragments: Past, Present, and Future talk, one of the future changes coming to Fragments is an opt in option to destroy Fragments on the back stack, rather than having two separate lifecycles. This isn't available as of yet.

You have to null out your references to the views in onDestroyView as that's the sign that the view is no longer being used by the Fragment system and it can be safely garbage collected if it wasn't for your continued reference to the View.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...