Avoid Memory Leaks and understanding of reference in Android
Memory
management is a serious problem for Android development. Memory leaks play a
very important role to achieve into it. Memory leak is when an object is no
longer being used but unable to be Garbage collected because it is still being
referenced some other places in the application.
As
a result, this unused object is occupying the memory resource even though it is
not being used by the application. Too much unused objects inside application
will cause not enough memory left for other active objects and finally leads
application crash with OutOfMemoryError.
That
means to take care of memory; you might need some different strategies such as:
Search
for memory leaks (Even when things aren't failing).
Keep
track of your references.
Different
Ways to Memory Leak in Android
Below
are few different ways which can lead the memory leak problem. So when you come
across following situations, make sure you handle it properly-
Static
Activities or Views
Inner
Classes
Anonymous
Classes
Threads
or Handlers
What is
Reference?
A
Reference consist addresses and class information about the object being
referenced. Assigning Reference will not create distinct copies of Objects. All
reference variables are referring to same Object.
Consider
Example –
Book
book1 = new Book();
Book
book2 = book1;
book1
is reference variable which contain the address of Actual Book Object.
book2
is another reference variable
book2
is initialized with book1 means – “book1 and book2” both are referring same
object , thus it does not create duplicate object , nor does it allocate extra
memory.
Types of
Reference
Depending
upon how objects are garbage collected, references to those objects in java are
grouped into 4 types.
1)
Strong References
2)
Weak References
3)
Soft References
4)
Phantom References
Let’s
discuss all these reference types in detail.
1) Strong
References
Strong
Reference is most simple as we use it in our day to day programming. Any object
which has Strong reference attached to it is not eligible for garbage
collection. A typical example is:
Book
book = new Book();
This
kind of reference makes the referenced object not eligible for Garbage Collection.
That is, whenever an object is referenced by a chain of strong Reference
Objects, it cannot be garbage collected.
In
general it works well as expected but below are the use case when creates a
huge problem:
AsyncTask
Strong Reference
public
class MainActivity extends Activity {
@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// AsyncTask creates strong reference
with the MainActivity
new MyAsyncTask().execute();
}
private class MyAsyncTask extends AsyncTask
{
@Override
protected Object
doInBackground(Object[] params) {
// do some stuff ;
}
}
}
Handler
Strong Reference
View
button = findViewById(R.id.button);
button.setOnClickListener(new
View.OnClickListener() {
@Override public void onClick(View v) {
// Handler creates strong reference
with button view
new Handler().postDelayed(new
Runnable() {
@Override
public void run() {
myTextBox.setText("Done");
}
}, 1000 * 10);
});
In
the above example AsyncTask created in Activity onCreate() method similarly
Handler inside Button View onClick(). Both has strong reference of
Activity/View. If both perform background work after the Activity has been
destroyed, the reference to the Activity will persist and it won’t be garbage
collected until after the background task completes. Therefore a leak can
occur.
2) Weak
References
Weak
reference object are automatically eligible for garbage collection. They are
likely to be garbage collected when JVM runs garbage collector thread. When an
object in memory is reachable only by Weak Reference Objects, it becomes
automatically eligible for garbage collector.
Below
is the example where AsyncTask has weak reference of MainActivity. So when
Activity destroyed, AsyncTask is holding its weak reference and it can be
collected by garbage collector. Therefore no memory leaks will happen.
public
class MainActivity extends Activity {
@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
// Pass the current activity
new MyAsyncTask(this).execute();
}
private static class MyAsyncTask extends
AsyncTask {
private
WeakReference<MainActivity> mainActivity;
// Default constructor
public MyAsyncTask(MainActivity
mainActivity) {
// Create a weak reference of
MainActivity
this.mainActivity = new
WeakReference<>(mainActivity);
}
@Override
protected Object
doInBackground(Object[] params) {
// do some stuff ;
}
}
}
3) Soft
References
A
soft reference object is similar to weak reference object that remains in
memory until memory is available and there is no risk of OutOfMemoryError. These
objects will be cleared from the memory only if JVM runs out of memory.
//Strong
Reference
Book
book = new Book();
//Creating
Soft Reference of Book type
SoftReference<Book>
softBook = new SoftReference<Book>(book);
book
= null; // Clear Book object so that
it is eligible for garbage collection.
book
= softBook.get(); //You can retrieve
back the object which has been softly referenced because it will be garbage
collected only when JVM needs memory.
Method
get() returns reference to the object if object is not cleared from the memory.
If object is cleared from the memory, it will return null.
4) Phantom
References
Phantom
reference object is directly eligible for garbage collection. JVM puts object
reference in a queue called ReferenceQueue before removing from memory. The
only use for phantom reference is keeping track of when object gets enqueued and
when it is removed from memory.
//Strong
Reference
Book
book = new Book();
//Creating
Reference Queue
ReferenceQueue<Book>
referenceQueue = new ReferenceQueue<Book>();
//Creating
PhantomReference Reference of Book type
PhantomReference<Book>
phantomBook = new PhantomReference<Book>(book,referenceQueue);
book
= null; // Clear Book object so that
it is eligible for garbage collection.
book
= phantomBook.get(); //It will be
garbage collected. But kept in ReferenceQueue before removing it from the
memory.
Conclusion
To
avoid memory leaks, Reference can be one of good solution. But WeakReference is not the only solution to
handle memory leak. There are some implementation designs, by which you can
avoid memory leak.
To find more interesting topics on Software development follow me at https://medium.com/@ankit.sinhal
You can also find my Android Applications on play store
Thank you so much for sharing this worth able content with us. The concept taken here will be useful for my future programs and i will surely implement them in my study. Keep blogging article like this.
ReplyDeleteAndroid Online Training
Check it Through Android Online Training For more info.
ReplyDelete