Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding memory leaks in Android application

I found the article "Avoiding memory leaks", where it is said that the following code:

private static Drawable sBackground;

@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);

  TextView label = new TextView(this);
  label.setText("Leaks are bad");

  if (sBackground == null) {
    sBackground = getDrawable(R.drawable.large_bitmap);
  }
  label.setBackgroundDrawable(sBackground);

  setContentView(label);
}

is not a good idea, since:

When the screen orientation changes the system will, by default, destroy the current activity and create a new one while preserving its state. In doing so, Android will reload the application's UI from the resources.

So the above code:

...leaks the first activity created upon the first screen orientation change. When a Drawable is attached to a view, the view is set as a callback on the drawable. In the code snippet above, this means the drawable has a reference to the TextView which itself has a reference to the activity (the Context) which in turns has references to pretty much anything (depending on your code.)

But, when screen orientation changes, the method setBackgroundDrawable(Drawable background) is called, which in turn calls:

background.setCallback(this);

The method Drawable.setCallback() is definied in the following way:

public final void setCallback(Callback cb) {
    mCallback = new WeakReference<Callback>(cb);
}

So, now background should release the old reference to the previous TextView, and a new reference to the new TextView should be created.

So, it seems like changing screen orientation leaks a reference only until the activity is newly created.

Where am I going wrong ?

like image 602
GVillani82 Avatar asked Oct 07 '14 20:10

GVillani82


People also ask

How do you identify memory leak in an Android application?

The Memory Profiler is a component in the Android Profiler that helps you identify memory leaks and memory churn that can lead to stutter, freezes, and even app crashes. It shows a realtime graph of your app's memory use and lets you capture a heap dump, force garbage collections, and track memory allocations.

How you detect a memory leak in an application?

To find a memory leak, you've got to look at the system's RAM usage. This can be accomplished in Windows by using the Resource Monitor. In Windows 11/10/8.1: Press Windows+R to open the Run dialog; enter "resmon" and click OK.

How do you explain memory leaks?

DEFINITION A memory leak is the gradual deterioration of system performance that occurs over time as the result of the fragmentation of a computer's RAM due to poorly designed or programmed applications that fail to free up memory segments when they are no longer needed.

What is memory leak in application?

Memory leaks are a class of bugs where the application fails to release memory when no longer needed. Over time, memory leaks affect the performance of both the particular application as well as the operating system. A large leak might result in unacceptable response times due to excessive paging.


1 Answers

You are absolutely right. However, there is one subtle point: the article is from 2009. Back then, the implementation of setCallback was different:

Android <= 2.3.7:

public final void setCallback(Callback cb) {
    mCallback = cb;
}

Android >= 4.0.1:

public final void setCallback(Callback cb) {
    mCallback = new WeakReference<Callback>(cb);
}

Grepcode shows no source code of intermediate versions, this is the only diff I could quickly find.


So, again, you're absolutely right in this specific case (if you're targeting >14 that is). However, it is still very important to really think about what is actually happening when you keep a static reference to such items (like you did). There are numerous cases where you certainly could be leaking the Context.

like image 91
nhaarman Avatar answered Oct 21 '22 06:10

nhaarman