[Android] Memory Leak debugging experience (1)

Source: Internet
Author: User

Http://rayleeya.javaeye.com/blog/727074

 

The memory leakage in Java development often brings us a lot of troubles. Especially for some new users, if you do not pay attention to some details at ordinary times, it is likely to cause very serious consequences.

Java Development in Android also has such problems. The PDF in the attachment lists some issues that need to be paid attention to when using the memory for Java Development in Android, hoping to help you.

 

Next article: [Android] Memory leakage debugging experience sharing (2) http://rayleeya.javaeye.com/blog/755657

 

Android Memory leakage debugging

Made by Li Wendong

Liwd@thunderst.com | rayleeya@gmail.com

2010-07-25 Friday

 

 

 

I. Overview 1

2. Poor code that is common in Android (Java) and is prone to memory leakage 1

(1) The cursor is not closed during database query. 2

(2) when constructing the adapter, the cached convertview 3 is not used

(3) Call recycle () to release memory when the bitmap object is not in use. 4

(4) Release object reference 4

(5) Other 5

Iii. Memory monitoring tool ddms --> heap 5

4. Memory analysis tool MAT (memory analyzer tool) 7

(1) generate the. hprof file 7

(2) Use mat to import the. hprof file 8

(3) Use Mat's View tool to analyze memory 8

 

 

I. Overview

Java programming is often overlooked, but a very important issue is memory usage. Android applications are mainly written in Java, so this problem also occurs in Android development. This article does not discuss Java programming, but sorts out such problems in Android, especially in application development.

Since the author has not been familiar with Android for a long time, please correct me if you have misstated it.

2. Common bad code in Android (Java) that is prone to memory leakage

Android is mainly used in embedded devices. embedded devices generally do not have high configurations due to some well-known restrictions, especially limited memory. If there are too many improper memory usage items in the code we write, it will inevitably make our devices run slowly or even crash. To ensure secure and fast running of Android applications, each android application uses a proprietary Dalvik Virtual Machine instance to run. It is incubated by the zygote service process, that is to say, each application runs in its own process. On the one hand, if the program encounters a memory leak during the running process, it will only kill its own process without affecting other processes (if it is a system process such as system_process, will cause the system to restart ). On the other hand, Android allocates different memory usage ceilings for different types of processes. If the memory used by the application process exceeds the upper limit, the system will consider the memory leakage and kill it. The maximum memory allocated by Android to application processes is as follows:

Location:/android_source/system/CORE/rootdir/init. RC Script

# Define the oom_adj values for the classes of processes that can be

# Killed by the kernel. These are used in activitymanagerservice.

Setprop Ro. foreground_app_adj 0

Setprop Ro. visible_app_adj 1

Setprop Ro. secondary_server_adj 2

Setprop Ro. backup_app_adj 2

Setprop Ro. home_app_adj 4

Setprop Ro. hidden_app_min_adj 7

Setprop Ro. content_provider_adj 14

Setprop Ro. empty_app_adj 15

 

# Define the memory thresholds at which the above process classes will

# Be killed. These numbers are in pages (4 K ).

Setprop Ro. foreground_app_mem 1536

Setprop Ro. visible_app_mem 2048

Setprop Ro. secondary_server_mem 4096

Setprop Ro. backup_app_mem 4096

Setprop Ro. home_app_mem 4096

Setprop Ro. hidden_app_mem 5120

Setprop Ro. content_provider_mem 5632

Setprop Ro. empty_app_mem 6144

 

# Write value must be consistent with the above properties.

# Note that the driver only supports 6 slots, so we have home_app at

# Same memory level as services.

Write/sys/module/lowmemorykiller/parameters/adj

 

Write/proc/sys/Vm/overcommit_memory 1

Write/proc/sys/Vm/min_free_order_shift 4

Write/sys/module/lowmemorykiller/parameters/minfree 1536,2048, 4096,5120, 5632,6144

 

# Set init its forked children's oom_adj.

Write/proc/1/oom_adj-16

 

Because our applications can use limited memory, we need to pay special attention to memory usage when writing code. The following are some common cases of improper memory usage.

 

(1) The cursor is not closed during database query.

Description:

The program usually queries the database, but it often does not close after using the cursor. If our query result set is small, memory consumption is not easy to find. Memory problems can be reproduced only when a large number of operations are performed at a regular time, this will cause difficulties and risks for future testing and troubleshooting.

 

Sample Code:

Cursor cursor = getcontentresolver (). Query (Uri ...);

If (cursor. movetonext ()){

......

}

 

Corrected sample code:

Cursor cursor = NULL;

Try {

Cursor = getcontentresolver (). Query (Uri ...);

If (cursor! = NULL & cursor. movetonext ()){

......

}

} Finally {

If (cursor! = NULL ){

Try {

Cursor. Close ();

} Catch (exception e ){

// Ignore this

}

}

}

 

(2) When constructing an adapter, no cached convertview is used

Description:

Taking constructing the baseadapter of listview as an example, the method is improved in baseadapter:

Public View getview (INT position, view convertview, viewgroup parent)

To provide listview with the view object required by each item. Initially, the listview will instantiate a certain number of view objects from the baseadapter based on the current screen layout, and the listview will cache these view objects. When you scroll up the listview, the view object originally located in the top list item will be recycled and then used to construct the bottom list item that appears. This construction process is completed by the getview () method, getview () the second view convertview parameter is the view object of the cached list item. (convertview is null if no view object is cached during initialization ).

From this we can see that if we don't use convertview, but re-instantiate a view object in getview () every time, it will be a waste of resources and time, which will also increase the memory usage. You can view the process when listview recycles the view object of list item:

Android. widget. abslistview. Java --> void addscrapview (view scrap) method.

 

Sample Code:

Public View getview (INT position, view convertview, viewgroup parent ){

View view = new XXX (...);

......

Return view;

}

 

Corrected 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) Call recycle () to release memory when the bitmap object is not in use

Description:

Sometimes we will manually operate bitmap objects. If a bitmap object occupies memory, when it is not in use, we can call bitmap. the recycle () method recycles the memory occupied by pixels of this object, but this is not necessary, depending on the situation. Let's take a look at the comments in the Code:

/**

* Free up the memory associated with this bitmap's pixels, and mark

* Bitmap as "dead", meaning it will throw an exception if getpixels () or

* Setpixels () is called, and will draw nothing. This operation cannot be

* Reversed, so it shoshould only be called if you are sure there are no

* Further uses for the bitmap. This is an advanced call, and normally need

* Not be called, since the normal GC process will be free up this memory when

* There are no more references to this bitmap.

*/

(4) Release Object Reference

Description:

This situation is difficult to describe. Two examples are provided.

Example:

Assume that the following operations are performed:

Public class demoactivity extends activity {

......

Private handler mhandler =...

Private object OBJ;

Public void operation (){

OBJ = initobj ();

...

[Mark]

Mhandler. Post (New runnable (){

Public void run (){

Useobj (OBJ );

}

});

}

}

We have a member variable obj. in operation (), we want to post the operation for processing the OBJ instance to the messagequeue of a thread. In the above Code, even if the thread where mhandler is located uses the object referenced by OBJ, this object will not be reclaimed because demoactivity. OBJ still has reference to this object. So if this object is no longer used in demoactivity, you can release the object reference at the [Mark] position, and the code can be changed:

......

Public void operation (){

OBJ = initobj ();

...

Final object o = OBJ;

OBJ = NULL;

Mhandler. Post (New runnable (){

Public void run (){

Useobj (O );

}

}

}

......

 

Example B:

Suppose we want to listen to the telephone service in the system in the lockscreen interface to obtain some information (such as signal strength), we can define a phonestatelistener object in lockscreen, register it with the telephonymanager service. For lockscreen objects, a lockscreen object is created when the screen lock interface needs to be displayed. When the screen lock interface disappears, the lockscreen object is released.

However, if you forget to cancel the previously registered phonestatelistener object when releasing the lockscreen object, lockscreen cannot be reclaimed. If the screen lock interface is constantly displayed and disappears, a large number of lockscreen objects cannot be recycled, causing outofmemory and causing the system_process process to crash.

In short, when an object a with a short life cycle is referenced by an object B with a long life cycle, at the end of a's life cycle, the references to a should be removed from B.

(5) Others

The typical release of resources in Android applications is in onpause (), onstop (), and ondestroy () during the activity lifecycle () method. This is a basic situation and is not described in detail here. For details, refer to the introduction to the activity lifecycle in the official documentation to determine when resources should be released.

  • _ Android_memory leakage ratio (583.9 KB)
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.