A GC memory leak problem with Android _android

Source: Internet
Author: User
Tags garbage collection memory usage static class

1. Android Memory leak concept

Many people think that Java programs, because there is garbage collection mechanism, there should be no memory leaks. In fact, if we do not use an object in a program, but because there is still a reference to it, the garbage collector can not recycle it, of course, the object occupied by the memory can not be used, which caused a memory leak. If our Java runs for a long time, and this memory leak continues to occur, there is no memory available at the end. Of course, Java, memory leaks and C + + is not the same. If the Java program is completely finished, all of its objects are unreachable, and the system can recycle them, and its memory leaks are limited to itself, without affecting the entire system. C + + memory leaks are worse, its memory leak is the system level, even if the C + + program exits, its leaked memory can not be recycled by the system, will never be available, unless the machine is restarted.

An Android application's memory leak has little impact on other applications. To enable the Android application to run safely and quickly, each Android application runs on a proprietary Dalvik virtual machine instance, which means that each application runs in its own process. Android allocates different memory usage caps for different types of processes, and if the application process uses more memory than the upper limit when the program is running, the system will be treated as a memory leak and killed, causing the process to kill itself It does not affect other processes (if it is a problem with system processes such as system_process, it can cause the system to reboot).

Memory Leak Example:

/* At this point, all object objects are not freed because the variable v refers to these objects. In fact, these objects are already useless, but are also referenced, the GC is powerless (in fact, GC think it is also useful), which is the most important cause of memory leaks. *
/vector v = new vector (a);   
for (int i = 1; i < i++)   {
  object o = new Object ();
  V.add (o);
  o = null;   
 }   

The object is iterated, and the object being applied is placed in a vector, and if the object itself is only released, it is not recyclable for the GC because the vector still references the object. Therefore, if the object is added to the vector, it must also be removed from the vector, and the simplest way is to set the vector object to null.

In general, the main reason for memory leaks in memory management is the object references that are preserved but are never used again.

2. The situation that causes the memory to leak

1 memory leaks caused by not shutting down resource objects

Resource objects such as (cursor,file files, etc.) tend to use some buffering, we do not use, we should close them in time, so that their buffer in time to reclaim memory. Their buffering exists not only in the Java Virtual machine, but also outside the Java Virtual machine. If we simply set its references to null without shutting them down, this can often result in memory leaks. Because some resource objects, such as Sqlitecursor (in the destructor Finalize (), if we do not close it, it will turn close () closed), if we do not close it, the system will also close it when it is recycled, but this is too inefficient. Therefore, when the resource object is not in use, it should call its close () function, turn it off, and then null. Make sure that our resource objects are closed when our program exits.

The operation of the query database is often done in the program, but there is often no shutdown after the cursor is used. If our query result set is relatively small, the memory consumption is not easy to find, only in the case of a large number of times to reproduce the memory problem, which will give future testing and troubleshooting problems and risks.

2 Some bad code into memory pressure

Some code does not cause memory leaks, but they, or the unused memory is not effective timely release, or not effective use of existing objects, but frequently request new memory, the memory of the recovery and allocation of a significant impact, it is easy to force the virtual machine to the application process to allocate more memory, Resulting in unnecessary memory overhead.

A Bitmap did not call recycle ()

When the bitmap object is not in use, we should first call recycle () to free the memory before it is set to null.

Although recycle () from the source, calling it should immediately release the main memory of bitmap, but the test results show that it does not immediately release memory. But I should still be able to greatly accelerate the release of bitmap's main memory.

b When constructing adapter, no cached Convertview is used

Taking the baseadapter of tectonic ListView as an example, the method is proposed in Baseadapter:

Public View GetView (int position, View Convertview, ViewGroup parent)

To provide ListView with the View object that each item requires. Initially ListView will instantiate a certain number of view objects from the Baseadapter based on the current screen layout, and ListView will cache the view objects. When the ListView is scrolled up, the View object originally located at the top of the list item is reclaimed and then used to construct the newly appearing bottom list item. This construction process is done by the GetView () method, and the second parameter view of GetView () is the view object of the cached list item (the cache does not have a view object when it is initialized Convertview is null )。

From this we can see that if we do not use Convertview, but each time in GetView () to instantiate a view object, that is, waste time, but also create memory garbage, to increase the pressure on garbage collection, if garbage collection too late, The virtual machine will have to allocate more memory to the application process, resulting in unnecessary memory overhead.

Layout.xml

 <?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android= 
"http://schemas.android.com/apk" /res/android "android:orientation=" vertical "android:layout_width=" fill_parent "android:layout_height=" 60dip ">
 <imageview android:id= "@+id/icon" android:layout_width= wrap_content "android:layout_height=" wrap_content "Android:layout_alignparentleft=" true "android:paddingleft=" 9px "/> 
 <textview android:id=" @+id/text " Android:layout_width= "Wrap_content" android:layout_height= "wrap_content" android:layout_torightof= "@id/icon" Android:textappearance= "Android:attr/textappearancemedium" android:paddingleft= "9px"/> 
 </ Relativelayout>

Code that can cause memory leaks: Badadapter.java

public class Badadapter extends Baseadapter {
  ...

  @Override public
  View getview (int position, View Convertview, ViewGroup parent) {
    log.d ("Myadapter", "Position: "+ Position +"---"
        + string.valueof (System.currenttimemillis ()));
    Final Layoutinflater Inflater = (layoutinflater) mcontext
        . Getsystemservice (context.layout_inflater_service);
    View v = inflater.inflate (r.layout.list_item_icon_text, null);
    ((ImageView) V.findviewbyid (R.id.icon)). Setimageresource (R.drawable.icon);
    ((TextView) V.findviewbyid (R.id.text)). SetText (Mdata[position));
    Return v.
  }
}

Corrective Optimization Sample code code: Goodadapter.java

public class Goodadapter extends Baseadapter {... @Override public view getview (int position, View Convertvie W, ViewGroup parent) {LOG.D ("Myadapter", "Position:" + Position + "---" + string.valueof (System.currenttimemi
    Llis ()));
    Viewholder Holder; if (Convertview = null) {final Layoutinflater Inflater = (layoutinflater) mcontext. Getsystemservice (Con Text.
      Layout_inflater_service);
      Convertview = inflater.inflate (R.layout.list_item_icon_text, NULL);
      Holder = new Viewholder ();
      Holder.icon = (ImageView) Convertview.findviewbyid (R.id.icon);
      Holder.text = (TextView) Convertview.findviewbyid (R.id.text);
    Convertview.settag (holder);
    else {holder = (Viewholder) convertview.gettag ();
    } holder.icon.setImageResource (R.drawable.icon);
    Holder.text.setText (Mdata[position]);
  return convertview;
    Static class Viewholder {ImageView icon;
  TextView text;

 }
}

Mainactivity.java

public class Mainactivity extends Listactivity {
  private badadapter/goodadapter madapter;

  Private string[] Marrdata;

  /** called the activity is a. * *
  @Override public
  void OnCreate (Bundle savedinstancestate) {
    super.oncreate (savedinstancestate);
    Setcontentview (r.layout.main);
    Marrdata = new string[1000];
    for (int i = 0; i < 1000 i++) {
      Marrdata[i] = "Google IO Adapter";
    }
    Madapter = new Badadapter/goodadapter (this, marrdata);
    Setlistadapter (Madapter);
  }


3) Improper use of threadlocal

If we rudely set the threadlocal to null without invoking the Remove () method or set (null), the threadlocal bound object can be recycled for a long time, resulting in a memory leak.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.