When you write code for software development, it is very important to understand where and when it is going to be executed. If you know these 2 points well, then only you can build awesome software.
In this tutorial our talk is mainly focused on Android App development, You know already Android apps run in a special environment in which each app is continuously monitored by the operating system to ensure better user experience to its users.
This kind of monitoring is required because it is running on small hardware devices, where hardware resources are shared by multiple applications based on their priority.
One of the main issues we face in android development is about memory. Managing memory is a very complicated task for Android OS. And every app is memory greedy also. They use this shared resource as their own property i.e, they are unaware of the current resource condition of the system.
Since we code it once and execute it many times, many places under many conditions, this makes resource management of a running Android app is a complicated task for its runtime environment.
Memory management of Android is about reclaiming the unused memory and allocate it to other apps if needed. It frees memory held up by the objects that are not in scope. The process of reclaiming memory is known as Garbage collection.
The Garbage Collector has to go through the references chain of an object before it frees the memory allocation. The determination of whether to free or keep it in memory is based on the object’s scope and type of reference to it.
Each app has a limited resource bucket. It has to do all its functionalities with allocated resources. If it needs more it has to manage the resources at the application level. That means, do not depend on GC.
If an object is referenced by any other classes with different scope then, in this case, GC will not free the object from memory. This will accumulate in heap. This problem is know as Memory Leak.
Leaking large objects like Activity or Fragment will quickly accumulate un-freed memory in heap and eventually crashes the app throwing “OutOfMemoryError”.
Creating a reference to Activity like objects is necessary for our application in some situations. But when you create a strong reference to Activity, it maight cause the above-mentioned problem. So the solution to this is to create WeakReference to Activity. In Java, a reference can be from strong to weak. Weak reference means GC will free the object memory if the scope found to be ended.
I will tell a Use Case, Let’s create an AsyncTask to call a Webservice to get some data and update it on UI once it got a response from the server. Here AsyncTask is an inner non-static class holding a strong implicit reference to the containing Activity. And activity destroyed before the network call could complete.
On the event of Activity destruction, GC checked for the scope of the object but it found that it is being used by AsynTask for an x-time. So decided not to free up the object at this moment. But onDestroy() was the perfect time to remove the memory allocation of an activity object but it missed the chance.
This leaks the Activity object. Addition to this, the next activity loaded into the memory before freeing up the old Activity. Please note, Each activity holds its own UI elements, these consists of images, files, UI elements, data set etc. Maybe the biggest objects used in apps come on the user interface. So leaking these objects for few seconds could run your app into OutOfMemoryError and crash.
WeakReference is definitely one of the solutions to avoid memory leaks in the Android application if it is difficult for you to create your app architecture using life cycle aware components.
Please check out the below-given sample Android project, that shows you how to make WeakReference to containing Activity class from an inner static AsynTask class without leaking memory.