ListView optimization and Memory leak issues

Source: Internet
Author: User

The most developed app makes it possible to have a memory leak due to the ListView. We know that memory leaks are bad. This means that the code writes a bit of a failure and needs some optimization changes.

After this lesson, and on the Internet to find some information, summed up, about the optimization of the ListView:

ListView Optimization Issues:
First, the ListView must be written in strict accordance with the Convertview and viewholder formats, so that the data can be optimally guaranteed.

Second, if the custom item involves pictures and so on, be sure to do picture optimization. Bitmap release can not be done.

Third, try to avoid using static in Baseadapter to define global static variables, which is very significant, static is a keyword in Java,

When you use it to decorate a member variable, that variable belongs to that class, not an instance of that class. So the variable with the static modifier, its life cycle is
For a long time, if you use it to refer to some resources that consume too many instances (such as context), you should avoid using them as much as possible.

Four, try to avoid using threads in the ListView adapter, because the main reason for a thread's memory leak is that the thread life cycle is uncontrollable.

Finally, if you do all of the above, your ListView is well-optimized. For your question, is the height of your listview control
Set to Fill_parent because wrap causes the ListView to slide infinitely to calculate its height. Does your text load do threads as well as multiple
Problem handling of the secondary repeated load. Whether the variable in your item is infinitely generating a new memory object multiple times, and so on.

We often encounter memory leaks in the process of doing projects, and there are often problems with oom in interviews.
Here, I will be the predecessors to solve the Andorid memory overflow method of re-organized, convenient for their later use.

First, the memory mechanism of Android

The Android application layer is developed by Java, and Android's Davlik virtual machine is similar to the JVM, except that it is register-based. In Java, the object is allocated memory through new, and all objects allocate space within the Java heap, while the release of memory is reclaimed by the garbage collector (GC). Java uses the principle of a forward graph. Java considers the reference relationship as a directed edge of the graph, and has a pointing edge from the referrer to the Reference object. The thread object can be the starting vertex of a roots graph, which is a tree starting from the starting vertex (GC), where the root vertex can reach objects that are valid objects, and the GC does not reclaim those objects. If an object (connected sub-graph) and this root vertex are unreachable (note that the graph is a forward graph), then we think that this (these) objects are no longer referenced and can be recycled by GC.


Second, the cause of memory overflow of Android

1. Memory leaks cause

Due to the error of our program, long-term maintenance of certain resources (such as the context) of the reference, the garbage collector will not be able to reclaim it, of course, the object occupied by the memory can not be used, resulting in a memory leak.

Common in Android is that activity is referenced after the call to finish is not released, the second time the activity is opened and re-created, such a memory leak occurs constantly, it will cause memory overflow.

Each Android application runs with a proprietary Dalvik virtual machine instance that is hatched by the zygote service process, meaning that each application runs in its own process. Android allocates different memory usage caps for different types of processes, and if a memory leak occurs during a program that causes the application process to use more memory than the upper limit, it will be considered a memory leak by the system and killed, which causes only its own process to be killed. Without affecting other processes.

2. More memory-intensive objects

Storing multiple objects that consume too much memory (such as bitmap) or loading a single oversized picture causes memory to exceed the limit.



Iii. common memory leak problems and their solutions


1. Memory leaks caused by reference not released

1.1 Memory leaks due to registration not canceled

This kind of Android memory leak is more serious than pure Java memory leaks, because some other Android programs may refer to the system's Android program objects (such as the registration mechanism). Even if the Android program is finished, other applications still have a reference to an object in the Android program, and the leaked memory is still not garbage collected.

1.2 Memory leaks caused by objects not cleaned in the collection

We usually add references to some objects to the collection, and when we don't need the object, we don't clean up its references from the collection, so the collection gets bigger. If the set is static, the situation is even worse.

1.3 Static

Static is a keyword in Java that, when used to decorate a member variable, belongs to that class, not an instance of that class.

private static Activitymcontext; Omitted

How can we effectively avoid the occurrence of such a reference?

First, you should avoid static member variables referencing resources that consume too many instances, such as context.

Second, the context as far as possible to use ApplicationContext, because the application context of the life cycle is relatively long, reference it will not be a memory leak problem.

See if the period of use is within the activity cycle, if exceeded, must use application; Common scenarios include: Asynctask,thread, third-party library initialization, and so on.
There are also situations where you can only use activity: for example, dialog boxes, various view, startactivity, etc.
In short, use application whenever possible.

Third, use WeakReference instead of strong references. For example, you can use weakreference<context>mcontextref;

1.4. Threads (use of internal classes)

The main reason for a thread's memory leak is that the thread life cycle is not controllable. If our thread is the inner class of activity, a reference to activity is saved in Mythread, and when Mythread's run function does not end, Mythread is not destroyed, so the old activity it references is not destroyed. Therefore, there is a memory leak problem.

If the method of a non-static inner class has a life cycle greater than its class, then there is a problem. For example: Asynctask, Handler, these two classes are convenient for developers to perform asynchronous tasks, but both of these jump out of the activity/fragment life cycle.
1.
Solution Solutions

First, the internal class of the thread is changed to a static inner class.

Reason:

Because a non-static inner class automatically holds an instance of the owning class, if an instance of the owning class has ended the life cycle, but the method of the inner class is still executing, its principal (reference) is held. It also causes the principal to not be released, i.e. memory leaks. Static classes are compiled and non-intrinsic classes are the same, with their own independent class names. Instances of the owning class are not silently quoted, so it is not easy to divulge.

Second, if you need to reference acitivity, use weak references.



2. Memory leaks due to resource object not shutting down

Resource objects such as (cursor,file files, etc.) often use some buffering, we should close them in time when we are not in use, so that their buffers can recover memory in time. Instead of waiting for the GC to handle it. Their buffering exists not only in the Java Virtual machine, but also outside the Java Virtual machine. If we simply set its reference to null without shutting them down, it often causes a memory leak. Because some resource objects, such as Sqlitecursor (in the destructor Finalize (), if we do not close it, it itself will close () closed), if we do not close it, the system will be recycled it also closed it, but this is too low efficiency. and the Android database on the cursor resource is also limited number of, if not close in time, will lead to other places can not be obtained.

3, some bad code into memory pressure

Some code does not cause memory leaks, but they do not use the memory of the effective and timely release, or do not effectively use the existing objects but frequent application of new memory, the memory of the recovery and allocation of large impact, it is easy to force the virtual machine to allocate more memory for the application process, Cause unnecessary memory expenses.

3.1 Bitmap did not call recycle ()

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

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

3.2 When constructing adapter, no cached Convertview is used

In order to construct the baseadapter of the ListView as an example, a method is proposed in the Baseadapter:

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

To provide the ListView with the View object that each item needs. Initially, the ListView instantiates a certain number of view objects from the Baseadapter based on the current screen layout, and the ListView caches the View objects. When you scroll up the ListView, the View object that was originally on the top list item is recycled and then used to construct the newly-appearing list item. This construction process is done by the GetView () method, and the second parameter view convertview of GetView () is the view object of the cached list item (the cache does not have a view object when it is initialized, and Convertview is null.) )。

It can be seen that if we do not use Convertview, but each time in the GetView () to re-instantiate a view object, that is, waste of time, also caused by 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.



Four, memory-intensive objects (pictures too large) caused by memory overflow and its solution

Because bitmap occupies a lot of memory, especially the resolution of large pictures, if you want to display more than the problem is more significant. The size of Android assigned to bitmap is only 8M.

Method 1: Zoom out of the picture

Sometimes, we want to show the area is very small, there is no need to load the entire picture, and only need to record a reduced image, when you can set a certain sampling rate, then you can greatly reduce the memory occupied.

1
Bitmapfactory.options Options = new Bitmapfactory.options ();
2
Options.insamplesize = 2;//Picture width is the original One-second, that is, the picture is the original One-fourth
Try not to use Setimagebitmap or Setimageresource or Bitmapfactory.decoderesource to set a larger picture,
Because these functions are finished decode, they end up with the Java layer's createbitmap, which consumes more memory.

Therefore, instead of using the Bitmapfactory.decodestream method first, create a bitmap, and then set it to ImageView source,
Decodestream's biggest secret is that it calls Jni>>nativedecodeasset () directly to complete decode,
There is no need to use Java layer CreateBitmap, which saves the Java layer space.

Method 2: Take a soft reference to the picture and do the recycle () operation in a timely manner

Although the system is able to confirm that the memory allocated by bitmap will eventually be destroyed, it is likely to exceed the Java heap limit because it consumes too much memory. Therefore, in the use of bitmap, should be timely recycle off. Recycle is not sure that the bitmap will be released immediately, but will give the virtual machine a hint: "The picture can be released."

Softreference<bitmap> Bitmap;
Bitmap = new softreference<bitmap> (PBITMAP);
if (bitmap! = null) {
if (bitmap.get () = null &&!bitmap.get (). isRecycled ()) {
Bitmap.get (). Recycle ();
bitmap = null;
}
}


Method 3: Single page, toggle N-Time after OOM on screen

1. See if there are any large pictures in the page layout, such as the background map. Remove the relevant settings from the XML and set the background map in the program (in the OnCreate () method):

1
drawable bg = getresources (). getdrawable (r.drawable.bg);
2
Xxx.setbackgrounddrawable (RLADDETAILONE_BG);


Note When Activity destory, bg.setcallback (null); Prevent the activity from being released in a timely manner.

2. Similar to the above method, directly load the XML configuration file into a view and put it into a container, and then call This.setcontentview (view view) directly, avoid the repeated loading of XML.



Method 4: Reuse as few code as possible while the page is switching. For example: Repeated calls to the database, repeated use of certain objects, etc...



Method 5:android Heap Memory can also define its own size and optimize the memory of the Dalvik virtual machine

--Reference: http://blog.csdn.net/wenhaiyan/article/details/5519567

Note: If you use this method: project build target can only select the <= 2.2 version, otherwise the compilation will not pass. So it is not recommended in this way.

V. Memory leak monitoring in Android

Memory Monitoring Tool DDMS--Heap


The use of the method is relatively simple:

· Select the Ddms view and open the Devices view and the heap view

· Click to select the process to monitor, for example: I chose system_process.

· Check the "Update heap" icon on the Devices view interface

· Click the Cause GC button in the heap view (equivalent to sending a GC request to the virtual machine)

Select the type you want to monitor in the heap view, generally we will observe the change of total size of DataObject, normally the value of total size will stabilize in a limited range, also say the code in the program is good, there is no case that the object in the program is not recycled. If an object reference is not released in the code, the total size of the data object does not come down significantly after each GC, and the total size increases as the number of operations increases. (Note: After selecting a good data object, continue to operate the application, so that you can see the total size changes). If the totalsize is indeed increasing without falling back, there is a resource reference in the program that has not been released. So how are we supposed to position it?

Memory leak targeting in Android

With the Ddms tool, you can tell if there is a memory leak in your application, so how do you locate the code snippet that has the problem and finally find the problem? Memory Analysis tool The mat memories Analyzer tool solves this challenge. The Mat tool is an Eclipse plugin and also has a separate RCP client, and the parsing file for the Mat tool is. Hprof, which holds a snapshot of a process's memory. The Mat tool locates the exact location of the memory leak in the following ways:

① generate the. hprof file. There are many ways to generate. hprof files in eclipse, which are generated in different versions of Android. Hprof are slightly different, but their overall mentality is the same. We select the app process that we want to analyze in the Ddms interface, and in the Row icon button above the Devices view interface, with the "Update Heap" and "Dump HPROF file" Two buttons selected, DDMS will automatically generate the. HPROF file for the currently selected process.

② the. hprof file into the Mat tool, the mat tool automatically parses and generates the report, clicks the "Dominator Tree" button, groups by package, selects the defined package classes right-click, and selects list Objects﹥with incoming from the popup menu. References, this will list all the suspicious classes. Right-clicking on an item and selecting the path to GC roots﹥excludeweak/soft References,mat Tool will further filter out all memory leaking classes associated with the program. This allows you to trace the specific code of a class that produces a memory leak.

The fundamental idea for finding a memory leak using the MAT memory analysis tool is to find out which class object's reference was not freed, then analyze why it was not released, and eventually navigate to which fragments in the code have a memory leak.

ListView optimization and Memory leak issues

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.