Android Memory leak Combat Analysis _java

Source: Internet
Author: User
Tags anonymous garbage collection message queue

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 memory to the stack (heap), so the written code is more secure.

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).

1. 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.)

2. The reason for the logical memory leak (logical memory leak) is that when the application no longer needs this object, all references to the 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:

The static variable for the global process (Process-global). This ignores the application of the state, holding the strong reference to the activity of the monster.

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.

1.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 ();
   }
);

2.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 ();
  }
);

3.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 ();
   }
);

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.

4.Anonymous Classes

Similarly, anonymous classes maintain references to external classes. So memory leaks can occur easily when you define anonymous Asynctsk in an 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 ();
  }
);

5.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 ();
  }
);

6.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 ();
   }
);

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

8.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 ();
      }
);

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.

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.