English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Analysis of memory overflow and prevention methods in Android programming

This article instance describes Android programming memory overflow and prevention methods. Shared with everyone for reference, as follows:

 Android's virtual machine is based on the register-based Dalvik, and its maximum heap size is generally16M. However, Android is written in Java, so to a large extent, Android's memory mechanism is equivalent to Java's memory mechanism. At the beginning of development, memory limitations can bring us serious problems such as memory overflow. When we do not use some memory, we should try to avoid saving necessary states on Android or other platforms when running other programs, so that some dead processes can cause memory problems, which should be released as much as possible when closing the program or saving the state, so as to improve the smoothness of the system operation.

The main manifestation of Android's memory is:

1On the Android platform, long-term retention of some resource references can cause some memory not to be released, leading to many memory leak issues. For example: Context (Activity mentioned below are all Context), when you need to keep the state of your first class object and pass it to other class objects, you must release the receiving class object first before removing the first class object. It is worth noting that: in the Java or Android memory mechanism, the root node must be guaranteed not to be called by other objects before it can be recycled and released by the system GC. Let's look at a piece of code:

@Override
protected void onCreate(Bundle state) {
   super.onCreate(state);
   TextView label = new TextView(this);
   label.setText("Leaks are bad");
   setContentView(label);
}

The meaning of this code is that we load an instance of TextView into the Activity (Context) we are running. Therefore, through the GC recycling mechanism, we know that to release Context, we must first release some objects that refer to it. If not, when you need to release Context, you will find that there will be a large amount of memory overflow. So it is very easy to have memory overflow by mistake. Saving some objects will also cause memory leaks. The simplest one is bitmap (Bitmap), for example: when the screen rotates, it will destroy the current Activity state being maintained and apply for a new Activity to be generated, until the new Activity state is saved. Let's look at another piece of 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);
}

This code is very fast but also incorrect. Memory leaks are likely to occur in the screen rotation direction. Although we may find that there is no explicit saving of the Context instance, when we connect the drawn image to a view, the Drawable will be set as a callback by the View, which means that in the above code, when drawing the TextView to the activity, we have already referenced this Activity. The link situation can be expressed as: Drawable->TextView->Context.

So when you want to release the Context, it is actually still stored in memory and has not been released.

How to avoid this situationThe main issue lies in threads. Do not underestimate threads; in Android, threads are most likely to cause memory leaks. The main reason for memory leaks caused by threads is the uncontrollable lifecycle of threads. Below is a piece of code:

public class MyTest 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
    }
  }
}

The code is simple, but new problems arise on Android, when we switch the view screen (landscape or portrait), a new Activity for landscape or portrait is created. We intuitively think that the previously created Activity will be recycled, but what is the actual situation? The Java mechanism does not give you the same feeling. Before we release the Activity, because the run function has not ended, MyThread has not been destroyed, and therefore the Activity (Mytest) that refers to it has not been destroyed either, which also leads to memory leaks.

Some people like to use Android's provided AsyncTask, but in fact, the problem of AsyncTask is more serious. Threads only appear this memory leak problem when the run function does not end, however, the internal implementation mechanism of AsyncTask uses ThreadPoolExecutor, the lifecycle of the Thread object produced by this class is uncertain and cannot be controlled by the application, so if AsyncTask is used as an inner class of Activity, it is more likely to cause memory leak problems.

There are mainly ways to improve thread issues:

① Change the inner class of the thread to a static inner class.
② Try to use weak references to save Context in the program.

2.Evil bitmap....

Bitmap is a very evil object. For a memory object, if the object occupies too much memory, when it exceeds the system's memory limit, the memory leak problem is very obvious.
The main solution to bitmap is to avoid saving it in memory as much as possible or to reduce the sampling rate. In many cases, because our image pixels are very high, and for the size of the mobile screen, we do not need such a high pixel ratio of images to load, we can first reduce the sampling rate of the image and then perform the original UI operations.

If we do not need to save the reference of bitmap objects, we can also use soft references as a substitute. There are many specific example codes on google.

In summary, to avoid memory leaks, mainly follow the following points:

First: Do not keep a long-term reference to Context (if you need to reference Context, make sure the lifecycle of the referenced object is consistent with itself).

Second: If you need to use Context, try to use ApplicationContext instead of Context, because the lifecycle of ApplicationContext is longer, and it will not cause memory leak problems in the case of referencing.

Third: Avoid using static variables in your Activity when you do not control the lifecycle of objects. Try to use WeakReference instead of a static variable.

Fourth: The garbage collector does not guarantee accurate memory recycling, so when using the content you need, mainly manage the lifecycle and timely release unnecessary objects. Try to release the objects we reference in onDestroy when the Activity's lifecycle ends, such as: cursor.close().

In fact, we can use less code to complete programs in many aspects. For example: we can use more9patch images, etc. There are many details that are worth discovering and mining more memory issues. If we can achieve C/C++Regarding the principle of 'who creates, who releases' for programs, our grasp of memory is not worse than Java or Android's own GC mechanism, and better control of memory can make our phones run more smoothly.

Readers who are interested in more about Android-related content can check the special topics on this site: 'Summary of Memory and Cache Techniques in Android Development', 'Android Development Tutorial for Beginners and Advanced', 'Summary of Debugging Techniques and Common Problem Solving Methods in Android', 'Summary of Multimedia Operation Techniques in Android (audio, video, recording, etc.)', 'Summary of Basic Component Usage in Android', 'Summary of View View Techniques in Android', 'Summary of Layout Layout Techniques in Android', and 'Summary of Control Usage in Android'.

I hope the description in this article will be helpful to everyone's Android program design.

Declaration: The content of this article is from the Internet, the copyright belongs to the original author, the content is contributed and uploaded by Internet users spontaneously, this website does not own the copyright, has not been manually edited, and does not assume relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#w3Please report via email to codebox.com (replace # with @) and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.

You may also like