Android Memory and memory overflow analysis detailed _android

Source: Internet
Author: User
One, the Android memory mechanism
Android's programs are written in the Java language, so Android's memory management is similar to Java's memory management. The programmer allocates memory to the object through new, and all objects allocate space within the Java heap, but the object's release is done by the garbage collector. C + + memory mechanism is "who pollution, who governance", the Java is more humane, give us a special cleaners (GC).
So how can GC confirm that an object has been discarded? Java uses the principle of a direction graph. Java refers to the reference relationship as a directed edge of a graph, with a directed edge pointing to a reference object from a reference. The thread object can be used as the starting vertex of a direction graph, which is a tree from the starting vertex, where the objects that the root vertex can reach are valid objects, and the GC does not recycle them. If an object (connected subgraph) is unreachable with this root vertex (note that the graph is a forward graph), then we think that the object is no longer referenced and can be recycled by GC.
second, the Android memory overflow
How does the memory overflow of Android happen?
Android's virtual machine is a register based Dalvik, its maximum heap size is generally 16M, and some machines are 24M. So the amount of memory space we can use is limited. If our memory footprint exceeds a certain level, there will be a outofmemory error.
Why is there a situation where there is not enough memory? I think there are two main reasons:
• Due to our program errors, long-term maintenance of some resources (such as the context) of the reference, resulting in memory leaks, resources caused by the release.
• Save multiple objects that consume large memory (such as bitmap), causing memory to go out of bounds.
The static of the evil
Static is a keyword in Java that, when used to decorate a member variable, belongs to that class rather than to an instance of the class. So the variable, which is decorated with static, has a long lifecycle, and if you use it to refer to some resource-consuming instances (most of the context), then be cautious.
Copy Code code as follows:

public class ClassName {
private static context Mcontext;
Omitted
}

The code above is dangerous if you assign the activity to a mcontext. So even if the activity has been ondestroy, the activity is still not released because the object still holds its reference.
Let's cite an example from the Android document.
Copy Code code as follows:

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);
}

Sbackground is a static variable, but we find that we do not explicitly save the Contex reference, but when drawable is connected to the view, drawable sets the view to a callback. Because the view is a reference to the context, we actually still have a reference to it. This reference chain is as follows:
Drawable->textview->context
So, eventually, the context is not released, and a memory leak occurs.
How can we effectively avoid the occurrence of such references?
First, you should try to avoid instances where static member variables refer to resources that are too expensive, such as the context.
Second, the context as far as possible to use the application, because the life cycle of the application is relatively long, reference it does not occur memory leaks.
Third, use WeakReference instead of strong references. For example, you can use weakreference<context> mcontextref;
The details of this section can also be referenced in the article section of the Android documentation.
all the threads are in trouble.
Threads are also an important source of memory leaks. The main reason threads generate memory leaks is that the thread lifecycle is not controllable. Let's consider the following piece of code.
Copy Code code as follows:

public class MyActivity extends activity {
@Override
public void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.main);
New Mythread (). Start ();
}
Private class Mythread extends thread{
@Override
public void Run () {
Super.run ();
Do somthing
}
}
}

This code is very common and very simple, is the form we often use. We think about a problem: Assuming that the mythread run function is a time-consuming operation, when we turn on the thread and turn the device's horizontal screen into a vertical screen, the activity is recreated in general when the screen is converted, and in our opinion, the old one should be destroyed. But that is not the case.
Since our thread is the internal class of the activity, a reference to the activity is preserved in the Mythread, and when the Mythread run function is not finished, Mythread is not destroyed, so the old activity referenced by it is not destroyed, As a result, there is a memory leak problem.
Some people like to use Android to provide the asynctask, but in fact the asynctask problem is more serious, thread only occurs when the run function does not end this memory leak problem, However, the implementation mechanism within the asynctask is the use of threadpoolexcutor, which produces a thread object that is indeterminate in its lifecycle and is beyond the control of the application, so if Asynctask as an internal class of activity, The problem of memory leaks is more likely to occur.
How should the memory leak caused by this thread be resolved?
First, change the inner class of the thread to the static inner class.
Second, a weak reference is used within the thread to save the context reference.
The model to be solved is as follows:
Copy Code code as follows:

Public abstract class Weakasynctask<params, Progress, result, weaktarget> extends
Asynctask<params, Progress, result> {
protected weakreference<weaktarget> Mtarget;
Public Weakasynctask (Weaktarget target) {
Mtarget = new weakreference<weaktarget> (target);
}
@Override
Protected final void OnPreExecute () {
Final Weaktarget target = Mtarget.get ();
if (target!= null) {
This.onpreexecute (target);
}
}
@Override
Protected final result Doinbackground (Params ... Params) {
Final Weaktarget target = Mtarget.get ();
if (target!= null) {
Return This.doinbackground (target, params);
} else {
return null;
}
}
@Override
Protected final void OnPostExecute (result result) {
Final Weaktarget target = Mtarget.get ();
if (target!= null) {
This.onpostexecute (target, result);
}
}
protected void OnPreExecute (Weaktarget target) {
No Default Action
}
Protected abstract result Doinbackground (weaktarget target, Params ... Params);
protected void OnPostExecute (weaktarget target, result result) {
No Default Action
}
}

In fact, threading is not just a memory leak, but it can also cause some catastrophic problems. Because this article is talking about memory issues, there is no discussion here.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.