Android prevents memory leaks and the use of mat

Source: Internet
Author: User

One of the most common cases of memory leaks in Android is the long-term retention of references to context, especially activity, so that activity cannot be destroyed. This also means that all the member variables in the activity are not destroyed. This article only describes how to avoid this situation, others such as bitmap not timely recovery caused by the oom exception is not discussed temporarily.

First, to prevent memory leaks

In what circumstances will the President keep a reference to an activity for a long time? There are two main types of cases:

1. A static variable keeps a reference to the activity

2. Threads keep References to activity

Because static variables are long-standing memory, they are not destroyed even after you call the Exit method. The life cycle of the thread is unpredictable. Once a screen has been cut, the activity cannot be destroyed. Let's look at a simple example:

[Java]View Plaincopy
  1. Public class Mainactivity extends Activity {
  2. @Override
  3. protected void OnCreate (Bundle savedinstancestate) {
  4. super.oncreate (savedinstancestate);
  5. Setcontentview (R.layout.activity_main);
  6. }
  7. public void OnClick (View v) {
  8. new MyThread (). Start ();
  9. }
  10. class MyThread extends thread{
  11. public Void Run () {
  12. try {
  13. Thread.Sleep (60000);
  14. } catch (Interruptedexception e) {
  15. //TODO auto-generated catch block
  16. E.printstacktrace ();
  17. }
  18. }
  19. }
  20. }

The thread mythread is the inner class of activity, what's the problem? We know that inner classes will hold references to external classes, which is the second case mentioned above. So how to optimize so that threads do not hold activity references? Familiar with Java immediately think of the static inner class, yes, as long as the definition of the mythread when adding a static, so that the inner class will not hold the external class reference.

In practical applications, however, threading problems tend to be much more complex. We may also use Asynctask or handler plus thread to get the data asynchronously and refresh the interface. In this case, if you simply define asynctask or handler as static, you cannot implement the function of refreshing the interface. The previous practice was to use weak references (weakreference), but after the 2.3 Android enhanced the recovery of weak and soft references, if the memory is not very sufficient, it is likely to cause your reference to be too early to be reclaimed by the system, and do not do the Refresh interface operation. The next example will provide a new solution:

[Java]View Plaincopy
  1. Public class Mainactivity extends Activity {
  2. private MyThread t;
  3. private String tag = "Tag";
  4. @Override
  5. protected void OnCreate (Bundle savedinstancestate) {
  6. super.oncreate (savedinstancestate);
  7. Setcontentview (R.layout.activity_main);
  8. }
  9. @Override
  10. protected void OnDestroy () {
  11. if (t! = null) {
  12. T.detach ();
  13. }
  14. Super.ondestroy ();
  15. }
  16. public void OnClick (View v) {
  17. if (t! = null) {
  18. T.detach ();
  19. }
  20. t = new MyThread ();
  21. Callback Callback = new Callback () {
  22. @Override
  23. public void Finish () {
  24. LOG.V (TAG, "Finish");
  25. }
  26. };
  27. T.attach (callback);
  28. T.start ();
  29. }
  30. static interface callback{
  31. void Finish ();
  32. }
  33. static class MyThread extends Thread {
  34. Callback Callback;
  35. void Attach (Callback Callback) {
  36. This.callback = callback;
  37. }
  38. void Detach () {
  39. if (callback! = null) {
  40. callback = null;
  41. }
  42. }
  43. public Void Run () {
  44. try {
  45. Thread.Sleep (60000);
  46. } catch (Interruptedexception e) {
  47. //TODO auto-generated catch block
  48. E.printstacktrace ();
  49. }
  50. if (callback! = null) {
  51. Callback.finish ();
  52. }
  53. }
  54. }
  55. }

The second example adds a callback based on the first example, and if you use Asynctask or handler, you can do the update interface within the callback. The most critical part is the detach method of the thread, which holds the callback member with the activity reference empty. Then we just have to make sure that all the variables that hold the reference will be empty before the activity is destroyed , so that the conditions for long-term activity references will not be valid. So you can see that the callback for an existing thread is empty before the OnDestroy method of the activity and the new thread.

Second, use mat to detect memory leaks

Mat is the memory analysis tool for Eclipse. I'll start with the installation, and combine the examples above to give you a quick overview of how to use this tool.

1. Installation

help--> Install New Software--Add, link is http://download.eclipse.org/mat/1.3/update-site/, it is best to check the "contact all Update sites ... "This option, or your eclipse may not have some packages that the plugin relies on. Click OK to wait for it to download the turtle speed. Restart eclipse after installation is ready to use.

2. Use

This tool can be used in conjunction with DDMS. Run our program first, then open the DDMS, select the program to analyze, click the Dump HPROF file button, wait a moment to see the memory of the detailed use of the situation.

3, combined with the above example analysis

Let's take a look at the pail null callback and comment out the OnDestroy and new thread part code. After running the program, open the DDMS and turn on the update Heap (in order to use the GC) and update thread (view thread). Then we run the thread and switch the horizontal screen, such as:

You can see that there is one more thread at this point (ID 9 in the figure). Open the mat, click on "Open Dominator Tree for Entrie heap" and finally click "Show as Histogram", where we can see the references to our various classes. Such as:

You can see that there are two references to mainactivity at this time. Return to DDMS, click on "Cause GC" (the Trash Can icon), open a new mat, continue to find mainactivity, if not unexpectedly, the mainactivity reference is still 2, that is, the previous activity is not recycled.

However, if you cancel the comment, the same operation, after clicking on the GC, found that Mainactivity's reference has changed back to 1.

Note: The above operations are best done before the thread execution is complete, and unfamiliar ones can take longer to look at the execution time setting.

III. recommendations

1, try not to keep the activity reference for a long time.

2, try to use application context to replace the context of activity. Because application is present in the entire life cycle of the program, it is not likely to be destroyed at any time as activity.

3. Avoid using static internal classes by statically holding member variables that are referenced by activity.

4, appropriate use of weak references.

5. If you do need to maintain a reference to the activity, you must ensure that the reference is canceled before the activity's life cycle ends.

Android prevents memory leaks and the use of mat

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.