Wednesday, January 18, 2012

Android Application Performance Improvement (using DDMS/Traceview/MAT tool): Part-4

Guys!! Here is the most awaited post on my blog!! The Performance analysis and Improvement ways by using Eclipse MAT tool !!

The Application Performance improvement process is one of the real challenges in the mobile application development. Android provides various tools to analyze the performance of the application, like-DDMS, Traceview, Allocation Tracker. The memory analysis can be done through Eclipse Memory Analysis Tool which a very powerful tool. It provides various analysis, like-Histogram, Dominator Tree, Leak Suspects along with chart analysis.

This post covers the memory analysis of an application, i.e. Stock Watch Application (which is one of my in-house developments) for an example, by using Eclipse MAT (Memory Analyzer Tool) tool and the improvements observed in the application performance on post-optimization.

Eclipse Memory Analysis Tool (MAT)

The Eclipse Memory Analyzer is a fast, feature-rich Java heap analyzer that helps to identify memory leakage. The Eclipse Memory Analyzer (MAT) provides a large selection of features to help in analyzing a single snapshot of heap. MAT can be used to identify memory leaks using a single click
In Android, DDMS helps you creating the heap dump HPROF file of the application. A Java heap dump is an image of the complete Java object graph at a certain point in time. It includes all objects, Fields, Primitive types and object references.
The Eclipse MAT helps to visualize based on Java heap dumps the references to objects and provides tools to identify potential memory leaks.
Heap Dump - Shallow Heap, Retained Heap
HPROF heap dump is a snapshot of a Java heap at a particular instance in time. The garbage collector is triggered before the dump is written. It contains information about all objects, all classes, GCR, and all information about the remaining objects. Heap does not contain allocation information.
Shallow heap is the total amount of memory used by all instances.
Retained Heap is the total amount of memory kept alive by all instances, including other objects that they have references to.
Eclipse MAT Pre-Optimization Analysis
On running the application, select the application process from the devices tab. DDMS helps to create the heap dump HPROF file of the application by selecting the ‘Dump HPROF file’ Button as shown in the below image.
It will ask for the type of report to be created. Select Leak Suspects Report and click Finish.
If we're running ADT (which includes a plug-in version of DDMS) and have MAT installed in Eclipse as well, clicking the “dump HPROF” button will automatically do the conversion (using hprof-conv) and open the converted hprof file into Eclipse (which will be opened by MAT).
Analysis Overview
It will display the overview of application performance analysis report like-total memory size no. of objects and no. of classes in the application, a pie chart showing biggest objects by retained size the application.
Also, it shows the various action items which produce the various analysis reports based on the different parameters as following:
Histogram lists number of instances per class.
Top Consumers prints the most expensive objects grouped by class and by package.
Leak Suspects displays the leak suspects and a system overview.
Top Components list report for components bigger than 1 percent.
Dominator Tree lists the biggest objects what they keep alive.
Duplicate Classes detect classes loaded by multiple class loaders.

Histogram
Using the Histogram view, we can filter the object/classes based on the package names, and you can see the incoming and outgoing references.

If we sort by shallow heap, we can see that instances of char [] are at the top. Right-click on the char [] class and select List Objects > with incoming references. This produces a list of all char arrays in the heap, which we can sort based on Shallow Heap usage.
Pick some of the big objects, and drill down on them. This will show the path from the root set to the object -- the chain of references that keeps this object alive.
In the above image, we have found some of the objects are using large memory as comparison to the other application objects as marked by red arrows. The array objects temp_data4 and temp_dataf are having more allocated memory than the memory they are consuming. Also, in object of Input Stream Class is open.


Note: MAT can't tell us for sure that this is a leak, because it doesn't know whether these objects are needed or not -- only the programmer can do that.
Top Consumers
It will show us which object and classes are the top consumers of memory in the application by using pie charts as shown below.

In the above image, we can analyze the biggest objects.

The above image is showing biggest top level dominator classes. As we can analyze that a large amount of memory is used by java.lang.class and java.lang.string classes.
Leak Suspects
We can get a higher level of leak suspect report with a pie chart and list of leak suspects as shown in below image.

From the above Leak Suspects report, we can analyse which objects/classes can cause the memory leaks. In this case, it is showing objects java.lang.string class as one of the leak suspects. For deep analysis on the specific objects for this class, we can also make use of Dominator tree.
Dominator Tree
The dominator tree is a data structure that allows you to answer the question about the biggest objects in almost no time. The dominator tree can also be used to find high memory usage in certain areas, which is a much harder problem.
Using the "dominates" relationship we can create a dominator tree out of the graph of objects in memory. At each node of this tree we store the amount of memory that would be freed (= retained size).
In the below image of Dominator tree, we can see class of our application and memory used by the different objects under this class.

Here we have found a many string arrays having some particular length. But they are using the full memory as of their defined lengths. As shown in the image, a string array of defined length 200 is containing only 39 items (e.g. string array is using only 39 positions out of 200, leaving empty the remaining positions).

Areas for Optimization

From the above performance analysis, we can see various areas of optimization in our application which is following.
·         java.lang.Class – we need to reduce the number of objects of this class
·         java.lang.String- The number of objects is quiet high, some of string arrays have defined length but still not being used fully.
We have found 9 string arrays of average lengths 250 defined in the activity where 8 arrays are not being used fully and containing the duplicate objects.
·         Lazy Initialization- we have found that the high number of String array objects looked suspicious. Also they retain not that much memory. So instead of always using the default constructor it would most likely better to use lazy initialization and only initialize the field when it's first needed. 
·         java.io.inputStream objects- Some of the Inputstream objects are not closed due to which the probability of leaks is more.

Post-optimization - Performance Analysis


Eclipse MAT Overview Analysis
The total amount of memory consumed by the application has been reduced from 2.3 MB to 2.2 MB. Also the number of total objects has been reduced.

Histogram
The inputstream objects has been closed as we can’t see memory allocated to in object in the below image. The objects of array strings are consuming less memory and not having vacant spaces as marked by red arrow in the image.

Top Consumers
If we compare the below image chart with the earlier one (e.g. before optimization), we have found that objects of BuySellHold class are not being counted in the biggest objects (in the place of (f) in the image)

Leak Suspects
We have reduced the probability ratios of the leak suspects of both the classes java.lang.Class  and java.lang.String as shown in below images


Dominator Tree


The Percentage memory consumed by the native class com.myapp.stockwatcher.BuySellHold class has been reduced from 2.5% to 1.8%. Moreover, the number of string arrays has been reduced to 1.

Performance Improvements

Improving application performance in terms of time and memory is one of the real challenges in mobile development. The android native tools like-DDMS/Traceview and Eclipse MAT plays a significant role in improving the performance. Also these performance tests can be executed during the development life cycle.
Following are the performance improvements by using both the tools:
v  Using MAT:

·         Memory consumption by the two activities has been reduced from 2.3 MB to 2.2 MB

·         Reduction in Percentage probability of the leaks suspects

·         Improved the program performance by reducing the java.lang.String objects

·         Reduction in Duplicate String arrays

·         Stream objects closed on time

Although, Performance improvement is an ongoing process, there will always be the scope of optimization. But by using these tools we can significantly reduce the time taken in optimization process as these tools enable us to hit the culprit areas directly.

Guys!! This post covers the most powerful tool analysis to improve android app performance. Post your comments!! J

Monday, January 16, 2012

Android Application Performance Improvement (using DDMS-Traceview/MAT tool): Part-3

DDMS - Viewing heap usage for a Process/Application
DDMS allows you to view how much heap memory a process is using. This information is useful in tracking heap usage at a certain point of time during the execution of your application. Also, you can invoke garbage collection, which enables the collection of heap data.
In DDMS, Devices tab is on left side from where you can select the device and the process running for your application and then, you can see the various log reports under different tabs on the right side.

Open the application in Eclipse which you want to analysis the performance.
Select DDMS from the Eclipse

On running the application, you can analyse the heap memory usage as well. In DDMS, after the selecting application process, select Heap tab from the right side panel.

In the Devices tab, select the process that you want to see the heap information for. Click the Update Heap button to enable heap information for the process as shown in the below image.


You can see total Heap size, Allocated & Free memory, percentage usage and no of objects. Also, the distribution of heap memory size and count is available in different types of objects like, free, data object, class objects, 1-byte array, 2-byte array etc. 
In the Heap tab, click Cause GC to invoke garbage collection, which enables the collection of heap data.
When the operation completes, you will see a group of object types and the memory that has been allocated for each type. You can click Cause GC again to refresh the data.
Click on an object type in the list to see a bar graph that shows the number of objects allocated for a particular memory size in bytes.
In Bar graph of Allocation count per size, you can analyse which size of objects are maximum/minimum in the application.
The performance of your application can be improved in terms of heap allocations to the objects.
Note: The next part of this post will cover the analysis by using a powerful tool Eclipse MAT. Keep an eye!! J

Android Application Performance Improvement (using DDMS/Traceview/MAT tool): Part-2

DDMS - Memory Allocation Tracker

DDMS provides a feature to track objects that are being allocated to memory and to see which classes and threads are allocating the objects. Memory Allocation Tracker allows the following:
  • Memory Usage
  • Tracking of memory allocated to objects
  • Tracking of threads & classes that are allocating objects
In DDMS, Devices tab is on left side from where you can select the device and the process running for your application and then, you can see the various log reports under different tabs on the right side.
On running the application, you can analyse the memory usage as well. In DDMS, after the selecting application process, select Allocation Tracker tab from the right side panel.
Select Start Tracking Button to start the memory allocation tracking. You can navigate through the application/screens where you want to track the memory usage.
Click Get Allocations to see a list of objects that have been allocated since you clicked on the Start Tracking button. You can click on Get Allocations again to append to the list new objects that that have been allocated.


It will display Allocation order, size, class and thread for each object. On selecting any object, it will fetch the details of selected object like, Class, Method, File and Line number in the file. This allows you to track, in real time, where objects are being allocated when you perform certain actions in your application. This information is valuable for assessing memory usage that can affect application performance.
Hope now you can take advantage of MAT tool(provided by DDMS) to improve the performance of your application.
Note: However, The Eclipse has also provided a MAT tool which provides quite a strong features to improve the application memory usage. The later parts of this post will cover it. Keep an eye!! J