I. Overview
In the Android memory leak Ultimate Solution (above) we described how to check whether an app has a memory leak, this article will summarize the typical memory leak code, and give the corresponding solution. The main problems with memory leaks can be grouped into the following types:
- Memory leaks caused by static variables
- Memory leaks caused by non-static internal classes
- Memory leak due to resource not shutdown
Second, the static variable caused by the memory leak
The life cycle of a static variable in Java begins when the class is loaded and ends when the class unloads. In other words, the life cycle in Android begins when the process starts and ends when the process dies. So in the course of the program's operation, if the process is not killed, static variables will always exist, will not be recycled. If a static variable strongly references a variable in an activity, the activity is also not released, even if the activity executes OnDestroy (do not perform ondestroy and be recycled). The solution to this type of problem is: 1. Look for alternatives that are similar to the life cycle of this static variable. 2. If you cannot find it, change the strong reference mode to a weak reference. The more typical examples are as follows:
A single case-induced context memory leak
public class Immanager {
private context context;
private static Immanager minstance;
public static Immanager getinstance {
if (minstance = null) {
synchronized (immanager.class) { C6/>if (minstance = = null)
minstance = new Immanager (context)
;
}
return minstance;
}
Private Immanager {
This.context = context;
}
}
When calling GetInstance, if the incoming context is the context of the activity. As long as the single case is not released, the activity will not be released.
Solution
The context of the incoming application, because the application context is longer than the activity, it can be understood that the application context is as long as the life cycle of the single instance, and it is most appropriate to pass it in.
public class Immanager {
private context context;
private static Immanager minstance;
public static Immanager getinstance {
if (minstance = null) {
synchronized (immanager.class) { C6/>if (minstance = = null)
//Converts the incoming context into the application context
minstance = new Immanager ( Context.getapplicationcontext ());
}
return minstance;
}
Private Immanager {
This.context = context;
}
}
Third, non-static internal class caused by memory leaks
In Java, a non-static internal class instance is created, and its outer instance is referenced. If this non-static internal class instance does some time-consuming operations, it causes the peripheral objects to not be reclaimed, resulting in a memory leak. The solution to this type of problem is: 1. Change the inner class into static inner Class 2. If you have a strong reference to a property in an activity, change the property's reference to a weak reference. 3. To end these time-consuming tasks when the activity executes ondestory, as the business allows.
Memory leaks caused by internal threads
public class Leakaty extends activity {
@Override
protected void onCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (r.layout.aty_leak);
Test ();
}
The public void Test () {
//anonymous inner class refers to its peripheral instance leakaty.this, causing a memory leak
new Thread (new Runnable () {
@Override
public void Run () {while
(true) {
try {
thread.sleep (1000);
} catch (Interruptedexception e) {
e.printstacktrace ();}}}
). Start ();
}
Solution
To modify a non-static anonymous inner class to a static anonymous inner class
public class Leakaty extends activity {
@Override
protected void onCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (r.layout.aty_leak);
Test ();
}
Static anonymous internal class public static
void Test () {
new Thread (new Runnable () {
@Override public
Void Run () {while
(true) {
try {
thread.sleep (1000);
} catch (Interruptedexception e) {
E.printstacktrace ();}}}
). Start ();
}
Memory leaks caused by handler
public class Leakaty extends activity {
@Override
protected void onCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (r.layout.aty_leak);
Fetchdata ();
}
Private Handler Mhandler = new Handler () {public
void Handlemessage (Android.os.Message msg) {
switch (msg.what) { Case
0:
//Refresh data break
;
Default: Break
;
}}; private void Fetchdata () {
//Get Data
mhandler.sendemptymessage (0);
}
}
Mhandler is an anonymous inner class instance that references a peripheral object leakaty.this, and if the handler still has messages to process when the activity exits, the activity is not recycled.
Solution
public class Leakaty extends activity {private TextView tvresult;
Private MyHandler handler;
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.aty_leak);
Tvresult = (TextView) Findviewbyid (R.id.tvresult);
Handler = new MyHandler (this);
Fetchdata ();
//First step, change the handler into static internal class.
private static class MyHandler extends Handler {//Step two, where the activity will need to be referenced, is changed to a weak reference.
Private weakreference<leakaty> atyinstance;
Public MyHandler (Leakaty aty) {this.atyinstance = new weakreference<leakaty> (aty);
@Override public void Handlemessage (msg) {super.handlemessage); Leakaty Aty = Atyinstance = null?
Null:atyInstance.get (); If the activity is released for recycling, these messages are not processed if (Aty = = null| |
Aty.isfinishing ()) {return;
} aty.tvResult.setText ("Fetch data Success"); }} private void Fetchdata () {//Get data handLer.sendemptymessage (0);
@Override protected void OnDestroy () {//step three to remove the callback Super.ondestroy () when the activity exits;
Handler.removecallbacksandmessages (NULL);
}
}
Iv. memory leaks due to resource not shutdown
When the use of Braodcastreceiver, Cursor, bitmap and other resources, when not needed to use, need to release in time, if not released, it will cause memory leaks.
To sum up, the main situation of memory leaks for the above three types, and ultimately boils down to a point, that is, resources do not need to be released when not. So in the process of coding to pay attention to these details, improve the performance of the program.