Java is a garbage collection language, the advantage is that developers do not have to deliberately manage memory allocation , reduce the application due to local failure (segmentation fault) caused by the crash, while preventing the release of the stack (heap) of the memory of the possibility of explosion, So it's safer to write code.
Unfortunately, there are still a lot of logic in Java that can easily lead to memory leaks (logical leak). If you're not careful, your Android app can easily waste memory that's not released, eventually causing the bug to run out of memory (Out-of-memory,oom).
The reason for the general memory leak (traditional memory leak) is that when all references to the object have been freed, the object has not been released. (Translator Note: Cursor forget to close etc.)
The reason for the logical memory leak (logical memory leak) is that when this object is no longer needed by the application, all references to that object are still not released.
If you hold a strong reference to an object, the garbage collector cannot reclaim the object in memory.
In Android development, the most easily raised memory leaks are the context. The context of an activity, for example, contains a large number of memory references, such as view hierarchies and other resources. Once the context is leaked, it also means leaking all the objects it points to. The Android machine has limited memory, and too much memory leaks can easily lead to oom.
Detecting logical memory leaks requires subjective judgment, especially when the life cycle of objects is not clear. Fortunately, the activity has a clear lifecycle and it is easy to spot the cause of the leak. Activity.ondestroy () is considered the end of the activity's life, and it should be destroyed in the program, or the Android system needs to recycle the memory (Android will recycle unseen activity when there is not enough memory).
If this method is done, there is still a strong reference on the stack that holds the activity, and the garbage collector cannot mark it as reclaimed memory, and our intention is to reclaim it!
The result is that the activity survives its life cycle.
Activity is a heavyweight object that should be handled by the Android system. However, logical memory leaks are always inadvertently occurring. (Translator Note: One activity has been tried to cause a 20M memory leak). In Android, the pitfalls that lead to potential memory leaks are of two kinds:
1. Static variable for global process (Process-global). This ignores the application of the state, holding the strong reference to the activity of the monster.
2. A thread that lives outside the activity lifecycle. A strong reference to the activity was not emptied.
Check to see if you have encountered the following situation.
Static Activities
A static activity variable is defined in the class, and the currently running activity instance is assigned to this static variable.
If this static variable is not emptied at the end of the activity lifecycle, it causes a memory leak. Because the static variable runs through the lifecycle of the application, the exposed activity will always exist in the application process and will not be reclaimed by the garbage collector.
static activity activity;
void Setstaticactivity () {Activity
= this;
}
View Sabutton = Findviewbyid (R.id.sa_button);
Sabutton.setonclicklistener (New View.onclicklistener () {
@Override public void OnClick (View v) {
Setstaticactivity ();
Nextactivity ();
}
);
Memory Leak 1–static Activity
Static views
Similar situations can occur in singleton mode, and it is useful to save an instance in memory if the activity is often used. As mentioned earlier, it is quite dangerous and unnecessary to force the life cycle of an activity to be prolonged, and it cannot be done in any way.
Special case: If a view initialization consumes a lot of resources and remains unchanged during an activity lifecycle, it can be static and loaded into the view hierachy, such that resources should be released when the activity is destroyed. (Translator Note: the example code does not release memory, this static view is null can be, but still do not recommend this static view method)
static view;
void Setstaticview () {
view = Findviewbyid (R.id.sv_button);
}
View Svbutton = Findviewbyid (R.id.sv_button);
Svbutton.setonclicklistener (New View.onclicklistener () {
@Override public void OnClick (View v) {
Setstaticview ();
Nextactivity ();
}
);
Memory Leak 2–static View
Inner Classes
Continue, assuming that there is an internal class in the activity, which can improve readability and encapsulation. Will be like we create an inner class, and hold a reference to a static variable, congratulations, the memory leak is not far away from you (translator Note: Empty when destroying, um).
private static Object inner;
void Createinnerclass () {
class Innerclass {
}
inner = new Innerclass ();
}
View Icbutton = Findviewbyid (R.id.ic_button);
Icbutton.setonclicklistener (New View.onclicklistener () {
@Override public void OnClick (View v) {
Createinnerclass ();
Nextactivity ();
}
);
Memory Leak 3–inner Class
One of the advantages of an inner class is that it can access the external class, which, unfortunately, causes the memory leak because the inner class holds a strong reference to the external class instance.
Anonymous Classes
Similarly, anonymous classes maintain references to external classes. So memory leaks are easy to happen when you define anonymous Asynctsk in activity
。 When an asynchronous task performs a time-consuming task in the background, the activity is unfortunately destroyed (the translator notes: The user exits, the system recycles), and the activity instance that is held by the asynctask is not reclaimed by the garbage collector until the asynchronous task ends.
void StartAsyncTask () {
new asynctask<void, Void, void> () {
@Override protected void doinbackground (void ... params) {while
(true);
}
. Execute ();
}
Super.oncreate (savedinstancestate);
Setcontentview (r.layout.activity_main);
View Aicbutton = Findviewbyid (R.id.at_button);
Aicbutton.setonclicklistener (New View.onclicklistener () {
@Override public void OnClick (View v) {
StartAsyncTask ();
Nextactivity ();
}
);
Memory Leak 4–asynctask
Handler
In the same way, define anonymous runnable, handler execution with anonymous classes. The runnable inner class holds an implicit reference to the external class, is passed to the handler message Queue MessageQueue, and the activity instance is not destroyed until the message messages are processed, resulting in a memory leak.
void Createhandler () {
new Handler () {
@Override public void handlemessage (Message message) {
Super.handlemessage (message);
}
. Postdelayed (New Runnable () {
@Override public void Run () {
while (true);
}
}, Long.max_value >> 1) ;
}
View Hbutton = Findviewbyid (R.id.h_button);
Hbutton.setonclicklistener (New View.onclicklistener () {
@Override public void OnClick (View v) {
Createhandler ();
Nextactivity ();
}
);
Memory Leak 5–handler
Threads
We again show memory leaks through thread and timertask.
void Spawnthread () {
new Thread () {
@Override public void Run () {while
(true);
}
}. Start ();
}
View TButton = Findviewbyid (R.id.t_button);
Tbutton.setonclicklistener (New View.onclicklistener () {
@Override public void OnClick (View v) {
Spawnthread ( );
Nextactivity ();
}
);
Memory Leak 6–thread
TimerTask
As long as an instance of an anonymous class, whether on a worker thread or not, holds a reference to the activity, causing a memory leak.
void Scheduletimer () {
new Timer (). Schedule (new TimerTask () {
@Override public
void Run () {while
true );
}
, Long.max_value >> 1);
View Ttbutton = Findviewbyid (R.id.tt_button);
Ttbutton.setonclicklistener (New View.onclicklistener () {
@Override public void OnClick (View v) {
Scheduletimer ();
Nextactivity ();
}
);
Memory Leak 7–timertask
Sensor Manager
Finally, system services can be obtained by context.getsystemservice (int name). These services work in their respective processes, helping to apply background tasks and handle hardware interactions. If you need to use these services, you can register the listener, which causes the service to hold a reference to the context, which can cause a memory leak if you do not unregister these listeners when the activity is destroyed.
void Registerlistener () {
Sensormanager Sensormanager = (sensormanager) getsystemservice (sensor_service);
Sensor Sensor = Sensormanager.getdefaultsensor (sensor.type_all);
Sensormanager.registerlistener (this, sensor, sensormanager.sensor_delay_fastest);
}
View Smbutton = Findviewbyid (R.id.sm_button);
Smbutton.setonclicklistener (New View.onclicklistener () {
@Override public void OnClick (View v) {
Registerlistener ();
Nextactivity ();
}
);
Memory Leak 8–sensor Manager
Summarize
Seen so many examples of memory leaks, it is easy to eat up the memory of the phone so that garbage collection processing more frequent, even the worst case will lead to oom. Garbage collection operations are expensive and can cause the naked eye to be visible to the cotton. So, when instantiated, pay attention to the chain of references held, and often carry out memory leak check.
The above is on the Android memory leak data collation, follow-up continue to supplement the relevant information, thank you for your support of this site!