Android Memory Analytics

Source: Internet
Author: User
Tags java reference

Getting Started with Mat

Word 4552 Read 746 Reviews 0 like

My blog address: http://androidperformance.com
This blog address: http://androidperformance.com/2015/04/11/AndroidMemory-Usage-Of-MAT/
This article Weibo address: http://weibo.com/270099576

About Mat

MAT, a Memory analyzer tool, is a fast, feature-rich Java heap Analysis tool that helps us to find memory leaks and reduce memory consumption. Use the Memory analysis tool to analyze from a multitude of objects to quickly calculate the size of objects in memory, to see who is preventing the garbage collector from recycling, and to visually look at the objects that may be causing the results through the report.


MAT

Of course, Mat also has a separate version that does not depend on eclipse, except that when debugging Android memory, the DDMS generated file needs to be converted before it can be opened on a standalone version of the mat. However, the tools are already available in the Android SDK, so it is convenient to use them.

Download and install the Mat tool

Here is the mat: https://eclipse.org/mat/downloads.php, available in three ways when downloading:


Download MAT

    • Update site This way there will be a URL: for example, http://download.eclipse.org/mat/1.4/update-site/, who installed the Eclipse plugin should know that Just copy the URL to the corresponding eclipse's install New software, and you can download it online.


      MAT with Eclipse

    • Archived update Site This way to install the same location as the previous one, except that the first is to download online, which is the use of offline packages to update, the disadvantage is that when the plug-in update, you need to re-download the offline package, and the first way you can download the update online.

    • Stand-alone Eclipse RCP Applications This approach is to use the mat as a standalone tool, no longer dependent on eclipse, for students who use Android studio without eclipse. The trouble with this approach is that DDMS exported files that need to be converted before they can be opened in a mat.

Once the download is installed, you can use the mat for the actual operation.

Common bad code in Android (Java) that is prone to memory leaks

Before using the Mat tool, you should have a basic understanding of how your Android memory is allocated, be sensitive to code that is prone to memory leaks, and troubleshoot memory leaks at the code level to help with memory usage.

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.

Common Memory misuse scenarios
  • Query database does not close cursors
    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}}}
  • When constructing adapter, no cached Convertview is used
    Description: To construct the baseadapter of a ListView, for example, a method is provided 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--and void Addscrapview (view scrap) method.

    Example code:

    public view GetView (int position, view Convertview, ViewGroup parent) {View view = new Xxx (...); ... return view;}

    Example Fix code:

    public view GetView (int position, view Convertview, ViewGroup parent) {View view = Null;if (Convertview! = null) {view = C Onvertview;populate (view, GetItem (position)); ...} else {view = new Xxx (...); ...} return view;}

    For the use and optimization of the ListView, refer to these two articles:

      • Using lists in Android (ListView)-Tutorial
        ]()

      • Making ListView scrolling Smooth

  • Bitmap object does not call recycle () to free memory when it is in use
    Description: Sometimes we manipulate bitmap objects manually, and if a bitmap object compares memory, you can call the Bitmap.recycle () method to reclaim the memory occupied by the pixels of this object when it is not in use.
    In addition to the latest version of Android development, use the following method can also release the memory occupied by this bitmap

    Bitmap Bitmap; Bitmap Initialize and use ... Bitmap = null;
  • Releasing a reference to an object
    Description: 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 Operat  Ion () {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.

  • 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.

Using Mat for Memory debugging

To debug memory, you first need to get the Hprof file, hprof file is the mat can recognize the file, Hprof file storage is a specific point in time, the Java process Memory snapshot. There are different formats for storing this data, which in general contains the case of Java objects and classes in the heap when the snapshot is triggered. Because the snapshot is just an instant thing, the heap dump cannot contain information about when, where, and in what way an object is assigned.

Get a hprof file using eclipse

This file can be exported using DDMS, DDMS in devices with a row of buttons, select a process (that is, in the list listed below devices Select the package name of the application you want to debug), click the Dump HPROF file button:


Dump HEAP with DDMS

The hprof file of the corresponding process can be obtained after the storage path is selected. The Eclipse plugin can be used to complete the above work one-click. Just click the dump HPROF file icon, then the mat plugin will automatically convert the format and open the analysis results in eclipse. Eclipse also has a dedicated memory analysis view, after the corresponding file, if the Eclipse plugin installed, then switch to the Memory Analyzer view. Using a standalone installation, use the tool that comes with the Android SDK (Hprof-conv location in Sdk/platform-tools/hprof-conv) to convert

Hprof-conv xxx.xxx.xxx.hprof Xxx.xxx.xxx.hprof

The converted. hprof file can be opened using the Mat tool.

Get hprof files using Android Studio

You can also export the corresponding hprof file using Android Studio:


Android-studio

The latest version of Android Studio has to right-click on the file to convert the standard hprof file, which can be opened in the mat.

Mat Main Interface Introduction

This is not the main interface of the Mat tool, but instead of importing a file, the overview interface is displayed.

  1. Open the converted Hprof file:


    Open Hprof

    If the first one is selected, a report is generated. This is no big deal.


    Leak Suspects

  2. Select the Overview interface:


    System Overview

    What we need to focus on is the following actions area


    Dominator Tree

      • Top consumers: List the largest object by graph


        Top Consumers

      • Duplicate Class: Automatically analyze the cause of leaks with mat

      • Histogram: Lists objects in memory, number of objects, and size


        Histogram

      • Dominator Tree: Lists the largest objects and their dependent on the surviving object (size is sorted by retained heap)

The general histogram and Dominator tree are the most commonly used.

Some concepts introduced in mat

To read the list of mat information, shallow heap, retained heap, GC root are some of the concepts that must be understood.

Shallow heap

Shallow size is the size of the object itself that occupies memory and does not contain the object it references.

    • The shallow size of a regular object (not an array) is determined by the number and type of its member variables.

    • The shallow size of an array is determined by the type of the array element (object type, base type) and the length of the set

Because unlike the C + + object itself can hold a lot of memory, Java object members are references. The real memory is on the heap, looks like a bunch of native byte[], char[], int[], so if we just look at the memory of the object itself, then the number is small. So we see that the histogram figure is sorted by shallow size, and the first second bit is Byte,char.

Retained Heap

The concept of the retained heap, which indicates that if an object is freed, it reduces the size of the heap that is consumed by all objects (including those that are released recursively) because of the object's release. Thus, if a member of an object is new to a large array of int, the int array can also be computed into this object. The heap,retained heap relative to the shallow can more accurately reflect the actual size of an object (because if the object is released, the retained heap can be freed).

The point here is that the retained heap is not always effective. For example, I have a new memory in a and assign a member variable to a. At this point I let B also point to this piece of memory. At this point, because both A and B refer to this memory, the memory is not freed when a is released. So this memory is not counted in the retained heap of a or B. To correct this, the leading object in mat, such as a or B, is not necessarily just an object, but it can be multiple objects. At this point, (A, B) The retained set of this combination contains the large memory. In the UI that corresponds to the mat, in histogram, you can select the Group by class, or the superclass or package to select it.

In order to calculate retained Memory,mat introduced the Dominator Tree. Join Object A references B and C,b and C and both refer to D (a diamond). At this point to calculate the retained Memory,a includes a itself and b,c,d. B and C because of the common reference D, so they both retained memory are just themselves. D of course it's just yourself. I think it's to speed up the calculation, the mat changes the object reference graph and transforms it into an object reference tree. In this case, the root is a, and B,c,d is his three sons. B,c,d no longer have a relationship with each other. By turning the reference graph into a reference tree, it is very convenient to calculate the retained heap and the display is very convenient. Corresponding to the Mat UI, in the Dominator tree view, the shallow heap and retained heap for each object are displayed. You can then look at the root of the node, step-by-step refinement to see where the retained heap is used. To put it this way, this conversion from graph to tree is really handy for memory analysis, but sometimes it can be confusing. Originally object B is a member of object A, but because B is also referenced by C, B is not under a in the tree and is probably a peer.

To correct this, right-click in the mat to select with outgoing references and with incoming references in the list objects. This is a real reference to the concept of a graph,

    • Outgoing references: Represents the Out node of the object (the object referenced by the object).

    • Incoming references: Represents the object's inbound node (the object referenced to the object).

To better understand the retained Heap, here is an example to illustrate:

The objects in memory are treated as nodes in, and objects and objects are referenced to each other. Here is a special node GC Roots, which is the starting point for the reference chain (reference chain):


Paste_image.png


Paste_image.png

Starting with obj1, the middle blue node represents only objects that can be accessed directly or indirectly through OBJ1. Because it can be accessed through GC roots, the OBJ3 on the left is not a blue node, whereas on the right the picture is blue because it is already contained within the retained collection.
So for the left, Obj1 retained size is obj1, obj2, obj4 shallow size sum;
The retained size of the image on the right is the sum of the obj4 size of Obj1, Obj2, obj3, shallow.
The obj2 retained size can be computed in the same way.

GC Root

The GC discovers that an object is not reachable through any reference chain (reference chain), and the object is recycled. The noun GC Roots is the starting point for the analysis of the process, such as the JVM itself ensuring the accessibility of the object (then the JVM is GC Roots), so the GC Roots is how to keep the object reachable in memory and, once unreachable, is recycled. Typically GC roots is an object on the call stack (the calling stack) on the current thread (for example, method parameters and local variables), or either the thread itself or the System class loader (the ClassLoader) The class that is loaded and the active object that native code (local code) retains. So GC roots is a powerful tool for analyzing why objects still exist in memory.

Some useful views in the matThread Ovewview

Thread Ovewview can view the thread information for this app:


Thread Ovewview

Group

In the histogram and Domiantor tree interfaces, you can choose to display the results in a different group (by default, group by Object), and switch to the group by package to better see which packages are in a larger class that takes up memory, It's also easy to locate your application.


Group

Path to GC Root

On an entry in histogram or domiantor tree, right-click to view its GC Root Path:


Path to GC Root

Here is also a description of the Java reference rules:
From the strongest to the weakest, different reference (reachable) levels reflect the life cycle of the object.

    • Strong ref (strong quote): Usually we write code that is strong Ref, which corresponds to strong accessibility, and the object is recycled only if you remove the strong.

    • Soft Ref (Soft Reference): corresponds to soft accessibility, so long as there is enough memory, the object is persisted until the memory is found to be tight and no strong Ref is collected. Generally available for caching, implemented through the Java.lang.ref.SoftReference class.

    • Weak ref (weak reference): is weaker than soft ref, and when no strong ref is found, the object is reclaimed immediately without waiting for the memory to be tight. Implemented through the Java.lang.ref.WeakReference and Java.util.WeakHashMap classes.

    • Phantom ref (Virtual Reference): No object is persisted in memory, you can only use Phantom ref itself. Typically used to perform a special cleanup process after entering the Finalize () method, implemented through Java.lang.ref.PhantomReference.

Click Path to GC Roots--with all references


Path to GC Roots

Reference documents
    1. Shallow and retained sizes

    2. Mat's Wiki:http://wiki.eclipse.org/index.php/memoryanalyzer

Android Memory Analytics

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.