Android Memory leak problem (i)

Source: Internet
Author: User
Tags lenovo

Objective

many people think Java programs , because there is a garbage collection mechanism, there should be no memory leaks.

In fact, if we no longer use an object in a program, but because there is still a reference to it, the garbage collector cannot reclaim it, and of course the memory used by the object cannot be consumed, which results in a memory leak. If our Java is running for a long time, and this memory leak is constantly occurring, then no memory is available. Java, of course , is not the same as the memory leaks and C + +. If the Java program is completely finished, all 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 leaks are system-level, even if the C + + program exits, its leaked memory can not be reclaimed by the system, never available, unless the machine is restarted.

AndroidThe memory leak of one application has little impact on other applications.to enable Android apps to run safely and quickly, each Android application uses a proprietary Dalvik virtual machine instance to run, and it is made up of zygote The service process is hatched, which means 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 while the program is running, which causes the application process to use more memory than this limit, it being killed by the system as a memory leak, which causes only its own processes to be killed without affecting other processes (if it is a problem with the system process such as system_process, it will cause a system reboot).

One, the reference does not release caused by the memory leak

1.1 . Memory leak caused by registration not canceled

this android memory leaks are more serious than pure Java memory leaks, as some other Android programs may refer to the objects of our anroid program (such as the registration mechanism). Even though our Android program is over, other reference programs still have a reference to an object in our Android program, and the leaked memory is still not garbage collected.

Like what

Suppose we want to listen to the telephony service in the system in the lock screen (lockscreen) to get some information ( such as signal strength, etc.), you can define a phonestatelistener in the Lockscreen object and register it with the Telephonymanager service. For Lockscreen objects, a Lockscreen object is created when the lock screen needs to be displayed , and the Lockscreen object is released when the lock screen disappears .

However, if you forget to cancel the Phonestatelistener object that we previously registered when releasing the Lockscreen object , it will cause Lockscreen to be garbage collected. If the lock screen interface is constantly displayed and disappears, it will eventually cause outofmemory due to the fact that a large number of Lockscreen objects have no way to be recycled, causing the system_process process to hang out .

Although some system programs, it seems that it can be automatically unregistered (of course, not in time), but we should still in our program clear cancellation, all registrations should be canceled at the end of the program. .

1.2 . Memory leak caused by collection container object not cleaned

we usually add references to some objects to a collection container (such as ArrayList), 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. Context leaksThe so-calledContext Leaks, in fact, more refers toactivity Leaks, this is a very vague case of outofmemoryerror. Let's look at an example from the Android website:
private static drawable Sbackground;      @Override protected void OnCreate (Bundle state) {super.oncreate (state);    TextView label = new TextView (this);      Label.settext ("Leaks is bad");    if (Sbackground = = null) {Sbackground = getdrawable (R.drawable.large_bitmap);      } label.setbackgrounddrawable (Sbackground);  Setcontentview (label); }
This code is very efficient, but at the same time extremely wrong; it leaks the activity that was created at the start of the first screen orientation. When a drawable is attached to a view, view takes it as aCallbackSet to drawable. The code snippet above means that the static drawable has a TextView reference, and TextView has a reference to the activity (context type), in other words, drawable has more object references. Even if the activity is destroyed, the memory is still not released. In addition, a reference to a context that exceeds its own life cycle can also cause the context to not be recycled, causing a memory leak. So try to use application as the context type. This context has the same long life cycle as the application and does not depend on the activity's life cycle. If you are going to save a long time object and it needs a Context, remember to use the Application object. You can easily get application objects by calling Context.getapplicationcontext () or activity.getapplication (). Recently encountered a situation caused a context leak, that is, when the activity is destroyed, there are other threads in the non-stop. Summarize the issues you should be aware of to avoid a context leak:1Try to use application as the context type.2Note that the reference to the context does not exceed its own life cycle.3. Use the "static" keyword carefully for the context.4.In the context if the thread, must be in OnDestroy () in time to stop. 1.4. Misuse of the Static keywordWhen a member variable of a class is declared static, it belongs to the class and not to the object, and if we declare a large resource object (Bitmap,context, etc.) as static, then those resources will not be recycled as the object is recycled and will persist. So be cautious when defining member variables using the static keyword. 1.5. WebView Object not destroyedwhen we don't useWebViewobject, you should call itsdestory ()function to destroy it and release the memory it occupies, otherwise its memory will not be recycled for long periods of time, causing a memory leak 1.6, the abuse of the GridViewThe GridView and the ListView are not implemented the same way. The GridView view is not created on-the-fly, but is all kept in memory. For example a GridView has 100 items, although we can only see 10 items, but in fact the entire 100 items are in memory.

Ii. memory leaks due to resource object not shutting down

Resource objects such as (Cursor,File files, etc.) often use a few buffers, we should close them in time when not in use, so that their buffers in time to recover memory. Their buffers exist not only in java inside the virtual machine, also in outside the virtual machine. If we just set its reference to null, sqlitecursor (in destructors finalize () If we don't close it, it will tune close () close), and if we don't close it, the system will close it when it recycles it, but it's too inefficient. So close () function, close it, and then set it to null. when our program exits, make sure our resource objects are closed

The operation of querying the database is often done in the program, but there are often use complete Cursor The case is not closed after . 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 operations in a constant time to reproduce the memory problem, which will give future testing and troubleshooting difficulties and risks.

Third, 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 ()

Bitmap when the object is not in use , We should call Recycle () before it is set to null.

Although the bitmap can be recovered by Bitmapfinalizer to reclaim memory. But calling recycle () is a good habit

Before Android4.0, bitmap's memory is allocated in the native heap, and calling recycle () can immediately release native memory .

Starting with Android4.0, bitmap's memory is allocated in the Dalvik heap, which is the Java heap, and calling recycle () does not immediately release native memory . but calling recycle () is also a good habit.

can be done by dumpsys meminfo command to see the memory of a process.

Example: adb shell "Dumpsys meminfo com.lenovo.robin"

Run the results.

Applications Memory Usage (KB):

uptime:18696550 realtime:18696541

* * Meminfo in PID 7985 [Com.lenovo.robin] * *

Native Dalvik Other Total

size:4828 5379 N/a 10207

allocated:4073 2852 N/A 6925

Free:10 2527 N/A 2537

(PSS): 608 317 1603 2528

(Shared Dirty): 2240 1896 6056 10192

(Priv Dirty): 548 36 1276 1860

Objects

views:0 viewroots:0

appcontexts:0 activities:0

Assets:2 Assetmanagers:2

Local binders:5 Proxy binders:11

Death recipients:1

OpenSSL sockets:0

Sql

heap:0 memory_used:0

pagecache_overflow:0 malloc_size:0

For more information on memory statistics, please refer to the "Android Memory leak tool (memory statistics)"

3.2. Construction Adapter cache is not used when the Convertview

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)

objects are recycled, It is then used to construct the newly emerging List item The cache does not have a view

It can be seen that if we do not use Convertview, but each time in 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 is too late, the virtual machine will have to allocate more memory to the application process, resulting in unnecessary memory overhead. the process of retrieving the view object of the list item can be viewed by the ListView :

Android.widget.AbsListView.java-to-void Addscrapview (View scrap) method.

Example code :

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

View view = new Xxx (...);

... ...

return view;

}

To fix the sample code :

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

View view = null;

if (Convertview! = null) {

view = Convertview;

Populate (view, GetItem (position));

...

} else {

view = new Xxx (...);

...

}

return view;

}

3.3. Improper use of threadlocal

If we rudely set the threadlocal to null without invoking theRemove ()method or set (null), it is possible that objects that are bound by threadlocal may not be recycled for long periods of time, resulting in memory leaks. For more information on this, please refer to "Threadlocal memory leak" iv. memory leaks in JNI codeFor more information on this, refer to "JNI References and garbage collection"

Android Memory leak problem (i)

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.