I have a Fragment
which has a RecyclerView
.
In this RecyclerView
, I may occasionally download and display images (loaded with Glide into ImageView
.
So when I open the Fragment
, used memory may sometimes jump from around 30MB to around 100MB or even more.
After the Activity
that is holding the Fragment
is finished, the memory does not free up. It stays the same as before.
I checked Glide documentation and apparently we don't have to worry about freeing up Bitmaps
in RecyclerView
. This is a huge issue, because app often crashes due to OOM because of this.
How should I correctly handle freeing up memory when Fragment
is removed?
Edit: another observation
Another thing I noticed is that if I finish the Activity
and then start the same Activity
again. Memory will jump back down for a moment and then back up to 100MB, which leads me to believe that the memory is cleared before launching the Fragment
again.
Fragment DESTROYED If the fragment is removed, or if the FragmentManager is destroyed, the fragment's Lifecycle is moved into the DESTROYED state and sends the ON_DESTROY event to its observers. The fragment then invokes its onDestroy() callback. At this point, the fragment has reached the end of its lifecycle.
A Fragment represents a reusable portion of your app's UI. A fragment defines and manages its own layout, has its own lifecycle, and can handle its own input events. Fragments cannot live on their own--they must be hosted by an activity or another fragment.
Use replace() to replace an existing fragment in a container with an instance of a new fragment class that you provide. Calling replace() is equivalent to calling remove() with a fragment in a container and adding a new fragment to that same container. transaction. commit();
Register and create a developer profile to keep track of sessions you're interested in by saving them to My I/O.
Garbage Collection is sometimes a painful issue in Android. Most developers fail to consider this issue and just keep developing without any sense of resource allocation.
This will of course cause memory problems such as leaks, OOM and unnecessary resource binding. There is absolutely no automatic way to free up memory. You can not, under any circumstances, rely solely on the Garbage Collector
Whenever you pass the Fragment's or Activity's onDestroy() method, what you can and should do is erase any construct that shall no longer be required in the application. You can do the following :
What I ended up doing was creating an interface like
public interface clearMemory(){
void clearMemory();
}
and implementing it on every class, be it Activity, Fragment or a normal class (includes adapters, custom views, etc).
I would then call the method whenever the class was to be destroyed (because the app was being destroyed or whenever I felt need to do so. Careful not to dispose in normal runtime)
@Override
public void onDestroy(){
clearMemory();
}
public void clearMemory(){
normalButtonOnClickListener = null;
normalButton.setOnClickListener(null);
normalButton = null;
myCustomClass.clearMemory(); // apply the interface to the class and clear it inside
myCustomClass = null;
simpleVariable = null;
...
}
By implementing this in a systematic way, my applications' memory management has become easier and leaner. One can then then know/control exactly how and when the memory is disposed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With