Android Memory leak debug

Source: Internet
Author: User

I. Overview 1

Second, Android (Java) is prone to cause memory leaks of bad code 1

(a) The query database did not close the cursor 2

(ii) When constructing adapter, no cached Convertview 3 is used

(iii) Bitmap object is not in use call recycle () to free memory 4

(iv) Releasing a reference to an object 4

(v) Other 5

Three, memory monitoring tool DDMS---Heap 5

Iv. Memory Analyzer Tool MAT 7

(i) generating. hprof Files 7

(ii) Import. hprof Files using Mat 8

(iii) Analyze memory using the MAT's view tool 8

I. Overview

Java programming is often overlooked, but one of the most important is the problem of memory usage. Android apps are written primarily in the Java language, so this problem will also occur in Android development. This article does not discuss the problem of Java programming, but rather the collation of such problems in Android, especially in application development.

Because the author does not touch the Android time is not very long, so if there is a wrong description, please correct me.

Second, the common Android (Java) prone to cause memory leaks of bad code

Android is primarily used in embedded devices, and embedded devices are usually not highly configurable due to some well-known conditions, especially when memory is relatively limited. If we write code that has too much memory usage, it will inevitably make our device run slowly, or even crash. To enable Android apps to run safely and quickly, each Android application uses a proprietary Dalvik virtual machine instance that is hatched by the zygote service process, which means that each application runs in its own process. On the one hand, if the program in the process of running a memory leak problem, will only make their own process is killed, and will not affect other processes (if it is system_process and other system process problems, it will cause a system restart). On the other hand, Android allocates different memory usage caps for different types of processes, and if the application process uses more memory than this limit, it is considered a memory leak by the system and is killed. The upper memory limit that Android allocates for the app process is as follows:

Location:/android_source/system/core/rootdir/init.rc section Script

# Define The Oom_adj values for the classes of processes so can be

# Killed by the kernel. These is 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 would

# be killed. These numbers is in pages (4k).

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 is consistent with the above properties.

# Note that the driver is only supports 6 slots and so we had home_app at the

# Same memory level as services.

Write/sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15

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

Due to the limited memory available to our applications, there is a need to pay special attention to memory usage issues when writing code. The following are some common cases of improper memory usage.

(i) the query database did not close the cursor

Describe:

The process of querying the database is often done, but there are often cases where the cursor is not closed after it has been 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 operations in a constant time to reproduce the memory problem, which will give future testing and troubleshooting difficulties and risks.

Example code:

cursor cursor = getcontentresolver (). Query (URI ...);

if (Cursor.movetonext ()) {

... ...

}

To fix the 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

}

}

}

(ii) When constructing adapter, no cached Convertview is used

Describe:

To construct the baseadapter of the ListView as an example, the method is improved in 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, wasting resources is also a waste of time, it will also make memory consumption more and more. 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;

}

(iii) Bitmap object does not call recycle () to free memory when it is in use

Describe:

Sometimes we will manipulate the bitmap object manually, if a bitmap object compares memory, when it is not in use, you can call the Bitmap.recycle () method to reclaim the memory occupied by the pixel of this object, but this is not necessary, depending on the situation. You can look at the comments in the code:

/**

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

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

* SetPixels () is called, and would draw nothing. This operation cannot is

* Reversed, so it should is called if you is sure there is no

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

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

* There is no more references to this bitmap.

*/

(iv) Releasing a reference to an object

Describe:

This situation is more cumbersome to describe, with two examples to illustrate.

Example A:

Suppose you have the following actions

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 be able to post the operation that handles the obj instance to the MessageQueue of a thread. In the above code, even if the thread mhandler is using the object referenced by obj, the object will not be garbage collected because Demoactivity.obj still retains a reference to the object. So if you no longer use this object in Demoactivity, you can release the object's reference at [Mark], and the code can be modified to:

... ...

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 phone service in the system in the lock screen (lockscreen) to get some information (such as signal strength, etc.), you can define a Phonestatelistener object in the Lockscreen. Register it with the Telephonymanager service at the same time. 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.

In short, when an object A with a shorter life cycle has its reference by a long-life object B, at the end of A's life cycle, a reference to A is cleared in B.

(v) Other

The most typical use of Android applications is to be aware of the need to release resources in the life cycle of the activity, in the OnPause (), OnStop (), OnDestroy () methods, in the case of the appropriate release of resources. Since this is a very basic situation, it is not detailed here to see the official documentation on the activity life cycle to determine when resources should be released.

Turn http://rayleeya.iteye.com/blog/727074

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.