Transferred from: http://www.cnblogs.com/wisekingokok/archive/2011/11/30/2245790.html
Dalvik virtual machines support garbage collection, but that doesn't mean you don't have to worry about memory management. You should pay extra attention to the memory usage of your mobile device, which is limited in memory space above. In this article, let's look at how some memory profiling tools (profiling Tools) in the Android SDK help us to trim the memory usage of the application.
Some memory usage issues are obvious, for example, if the application has a memory leak every time the user touches the screen, it is possible to trigger OutOfMemoryError and eventually crash the program. Some of the other issues are subtle, perhaps only to reduce the performance of the application and the overall system (when running the garbage collector at high frequency and long time).
the necessary tools:
The Android SDK provides 2 main tools for profiling application memory usage: A paging allocation tracker and heap dumps in DDMS. Allocation Tracker is useful, especially when you want a perceptual understanding of how the program allocates memory in a certain amount of time. But it cannot give you any information about the overall situation of the program heap. For more information about allocation Tracker, see the article Tracking Memory allocations. The rest of the article will focus on heap dumps, which is a more powerful memory analysis tool.
A heap dump is a snapshot of the program heap, which is saved as a binary format called Hprof. Dalvik is used in a similar format, but not exactly the same. Here is the Java hprof tool. There are many ways to generate a heap dump of a run-time application. One is to use the Dump HPROF file button inside the DDMS. If you want to produce more accurate dump data, you can use the Android.os.Debug.dumpHprofData () method in your program.
To analyze heap dump, you can use some standard tools such as Jhat or Eclipse Memory Analyzer (MAT). First, however, you need to convert the. hprof file from the Dalvik format to the J2SE hprof format. You can use the Hprof-conv tool provided by the Android SDK. For example:
- Hprof-conv dump.hprof Converted-dump.hprof
To debug a memory leak instance:
In the Dalvik runtime, the programmer cannot explicitly allocate and free memory, so the memory leaks here are different from those in C and C + +. Inside your code, a memory leak is a reference to a class object that you have reserved and no longer need. Sometimes just one reference blocks the GC's collection of a large stack of objects.
We have come to a practical example of the Android SDK that provides the sample program Honeycomb Gallery sample App. It is a photo gallery program used to demonstrate the use of some new honeycomb APIs. (Download and compile the code, see these commands.) We will intentionally add a memory leak inside the program and then demonstrate how to debug it.
Imagine that we want to modify the program so that it downloads images from the web. To make it more flexible, we can consider implementing a cache to save recently viewed images. We can make some minor changes to Contentfragment.java to achieve this goal. At the top of class, we add a new static variable:
- Private static hashmap<string,bitmap> Sbitmapcache = new hashmap<string,bitmap> ();
This is where we save the cache. Now we can modify the Updatecontentandrecyclebitmap () method to see if the data already exists before downloading it, and then to download it if it does not exist, and then add the data to the cache.
- void Updatecontentandrecyclebitmap (int category, int position) {
- if (mcurrentactionmode! = null) {
- Mcurrentactionmode.finish ();
- }
- //Get the bitmap that needs to be drawn and update the ImageView.
- //Check If the Bitmap is already in the cache
- String bitmapid = "" + Category + "." + position;
- Mbitmap = Sbitmapcache.get (bitmapid);
- if (Mbitmap = = null) {
- //It's not at the cache, so load the Bitmap and add It to the cache.
- //danger! We Add items to this cache without ever removing any.
- Mbitmap = directory.getcategory (category). Getentry (position)
- . Getbitmap (Getresources ());
- Sbitmapcache.put (Bitmapid, Mbitmap);
- }
- ((ImageView) GetView (). Findviewbyid (R.id.image)). Setimagebitmap (Mbitmap);
- }
I have intentionally introduced a memory leak problem here: We have added images to the cache but never removed them. In real-world applications, we can use some way to limit the size of the cache.
Check the usage of the heap in DDMS
Dalvik Debug Monitor Server (DDMS) is one of the main Android debugging Tools and is part of ADT Eclipse Plug-in, and the standalone version of the program can be found under tools/in the root directory of the Android SDK. For more information on DDMS, please refer to using DDMS.
Let's use DDMS to check the heap usage of this app. You can use the following two methods to start DDMS:
- From Eclipse:click windows > Open perspective > Other ... > DDMS
- or from the command Line:run
ddms (or to ./ddms mac/linux) in the tools/ directory
Select the process com.example.android.hcgallery on the left panel and click the Show heap Updates button on the top of the toolbar. This time switch to DDMS's VM heap paging. It displays some basic data for the heap memory after each GC. To see the data content after the first GC, click the Cause GC button:
We can see now that the value (allocated column) is some more than 8MB. Now slide the photo and see the data growing. Because only 13 photos in the program inside, so leaked memory only so large. To some extent, this is the worst kind of memory leak, because we can't get outofmemoryerror to remind us that we're out of memory now.
Generate Heap Dump
We now use heap dump to track this problem. Click the Dump Hprof file button above the Ddms toolbar, select the file storage location, and then run Hprof-conv. In this example we use the standalone Mat version (version 1.0.1), which is downloaded from the mat site.
If you use ADT (which contains DDMS plugins) and also install the mat in eclipse, click "Dump HPROF" The button will automatically convert (with Hprof-conv) and open the converted Hprof file in eclipse (it actually opens with a mat).
Analyze heap dumps with mat
Start the mat and load the Hprof file we just generated. Mat is a powerful tool to tell that all of its features are beyond the scope of this article, so I just want to demonstrate a way you can detect leaks: the histogram (histogram) view. It shows a list of class instances that can be sorted, including: Shallow heap (total memory usage for all instances), or retained heap (the sum of memory allocated for all class instances, including all of their referenced objects).
If we sort by shallow heap, we can see byte[] instances at the top. Since Android3.0 (Honeycomb), bitmap's pixel data is stored in a byte array (previously stored in the heap of Dalvik), so judging by the size of this object, needless to say, it must be the bitmap we leaked out.
Right-click the byte[] class and select list Objects > with incoming references. It generates a list of all byte arrays on the heap, and in the list we can sort by the usage of the shallow heap.
Select and expand a larger object that will show the path from the root to the object--a chain that guarantees that the object is valid. Watch out, this is our bitmap cache!
Mat doesn't tell us that this is a leak, because it doesn't know if this thing is a program that needs to be made, only the programmer knows. In this case, the large amount of memory used by the cache affects the later applications, so we can consider limiting the size of the cache.
Compare heap dumps with mat
When debugging memory leaks, it is sometimes useful to compare the heap state of 2 places in a timely manner. Then you need to generate 2 separate hprof files (don't forget to convert the format). Here are some details on how to compare 2 heap dumps in mat (with a bit of complexity):
- The first hprof file (using file > Open Heap Dump ).
- Open histogram view.
- In Navigation history view (if you can't see it from Window > Navigation History), right-click histogram and select Add to Compare Basket .
- Open a second hprof file and redo steps 2 and 3.
- Switch to Compare basket view, and then click Compare the Results (the Red "!" in the upper right corner of the view!) icon).
Summarize
In this article, I show you how allocation tracker and heap dumps give you a perceptual understanding of the application's memory usage. I've also shown that Eclipse memory Analyzer (MAT) can help chase the leak in our program. Mat is a powerful tool, I just touch some fur, if you want to learn more, I suggest reading some of the following articles:
- Memory Analyzer News:eclipse MAT Project's official blog.
- Markus Kohler's Java Performance Blog has many useful articles, including analysing the Memory Usage of Android applications with the Eclipse Memory Analyzer and useful Tips for the Eclipse Memory Analyzer.
Android Official Blog-memory analytics for Android Apps (translate) (RPM)