Android Memory Leak Ultimate Solution (next) _android

Source: Internet
Author: User

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.

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.