⬆️ ⬇️

Memory Analysis for Android Applications

Dalvik has a garbage collector, but that does not mean that you can ignore memory management. Quite the contrary - you need to be especially careful when using memory, which, as you know, is limited on mobile devices. In this article, we will look at tools that significantly help monitor how an application uses memory.





Some problems from overuse of memory are quite obvious. For example, in your application a memory leak constantly occurs when the user touches the screen, then this eventually may cause OutOfMemoryError , and the application will crash and close. Other problems that are more subtle than this may lead to a general decline in the performance of the application and the system as a whole (because the garbage collector will be called more frequently and for a longer time).



Instruments



The Android SDK provides two primary devices for profiling application memory usage: the Allocation Tracker tab in DDMS and heap dumps. Allocation Tracker can be useful when you want to learn about memory usage in a specific period of time, as it does not provide information about the full state of the heap that is allocated for an application. For more information about Allocation Tracker, see the article Tracking Memory Allocations . The rest of this article will be devoted to the study of heap dumps, as this is a more powerful tool.

')

A heap dump is a snapshot of the entire heap of an application that is stored in a binary file, HPROF format. Dalvik uses a format that is similar to the one used by the HPROF tool in Java, but is not exactly the same.



There are several ways to create a heap dump of an running Android application. The first is to use the Dump HPROF file button in DDMS. If you need to choose the moment of creating the dump more precisely, you can create it programmatically using the android.os.Debug.dumpHprofData () method.



For analysis, you can use the standard jhat tool or Eclipse Memory Analyzer (MAT) . However, you first need to convert the .hprof file from Dalvik format to J2SE HPROF format. To do this, use the hprof-conv utility, which comes with the Android SDK:



hprof-conv dump.hprof converted-dump.hprof 




Example: Debugging Memory Leaks



In Dalvik, a programmer does not explicitly place anything in free memory, so there may be leaks, as in C and C ++. By "memory leak" is usually understood a situation in which you continue to refer to an object that is no longer needed. Sometimes, a single reference can prevent a call to the garbage collector to remove a large set of objects.



Let's look at the Honeycomb Gallery sample app from the Android SDK. This is a simple photo gallery that demonstrates the use of some new API methods in Honeycomb. We will now intentionally create a memory leak to demonstrate the debugging method.



image




Imagine that we want an application to receive images over the network. To make it more responsive to the user, it may be worthwhile to implement a cache for storing recently viewed images. We can do this by making some changes to ContentFragment.java . At the beginning of the class, declare and initialize a new variable:



  private static HashMap<String,Bitmap> sBitmapCache = new HashMap<String,Bitmap>(); 




In this display, we will cache the loaded Bitmap's. Now you can change the updateContentAndRecycleBitmap () method to check the cache before loading and add Bitmap to the cache after loading:



  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 in 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); } 




Here, I deliberately created a memory leak: Bitmaps are added to the cache, but not removed from it. In a real application, it is obvious that the cache size needs to be limited.



Heap Examination with DDMS



Dalvik Debug Monitor Server (DDMS) is one of the main debugging tools in Android. It is part of the ADT plug-in to the Eclipse development environment, and can also be found in the tools / folder of your Android SDK. For more information, see Using DDMS .



Let's use DDMS to analyze the use of the heap by our application. You can run DDMS in two ways:





image




Select the com.example.android.hcgallery process in the left pane and click on the Show heap updates button on the toolbar. Then switch to the VM Heap VM tab in DDMS. You will see some basic heap usage information that will be updated each time the garbage collector is called. To see the first update, click on the Cause GC button.



image




You can see that “live” objects occupy a little less than 8Mb in memory (see the Allocated column). Now scroll through the photos, and you can see how this number is increasing. Since the application has only 13 photos, the memory leak is limited. In a sense, this is the worst case that can happen, so OutOfMemoryError will never be here .



Creating a heap dump



Click on the Dump HPROF file button in the DDMS toolbar, select where to save the file, and convert it using the hprof-conv utility. In this example, we will use a separate version of MAT (1.0.1), it can be downloaded here .



If you use Eclipse, with MAT installed, then after pressing the “dump HPROF” button, the file is automatically converted and opened in the Ecilpse window.



Heap dump analysis using MAT



Run MAT and download the HPROF file that you just created. MAT is a powerful utility, and an explanation of all its features outside of this topic, so I will explain only one of the methods of how to determine the leakage - using the Histogram view. In this view, you can see a list of classes sorted by the number of instances, shallow heap (total memory size occupied by instances), or retained heap (total memory occupied by instances and the objects they refer to).



image




If you sort by shallow heap , you can see that at the top is the number of byte [] instances. In Android 3.0, Bitmaps are represented as arrays of bytes, the size of which depends on the size of the Bitmap. That is, it is clear that they represent the memory that deals with our bitmaps. Right-click on the byte [] class and select List Objects> with incoming references. You will see a list of all the arrays from the bytes located on the heap.



Select one of the large objects and expand it. As a result, you will see the entire chain of links, which is formed due to this object. Here it is - our cache for Bitmap!



image




MAT cannot give accurate information whether this is a leak, as it does not know whether these objects are needed. Only the programmer knows the answer. In our case, the cache is very large compared to the entire application, so it would be logical to limit its size.



Comparing Heap Dumps with MAT



When debugging memory leaks, it is useful to compare the state of the heap at different times. To do this, create two HPROF files (don't forget to convert them with the hprof-conv utility).



Here is how you can compare these two files:

  1. Open the first file ( File> Open Heap Dump ).
  2. Open histogram view.
  3. In the form of a navigation history (Window> Navigation History), right-click on histogram and select Add to Compare Basket .
  4. Open the second file and repeat steps 2 and 3.
  5. Switch to the Compare Basket view, and click Compare the Results (the red exclamation mark icon in the upper right corner)




Conclusion



In this article, I showed how Allocation Tracker and heap dumps can help you analyze memory usage. I also showed how MAT helps track down memory leaks in an application. If you want to learn more about MAT, you can read the following articles:

Source: https://habr.com/ru/post/116163/



All Articles