How to analyze application memory in android (17) - Use MAT to view the Android heap
The previous article introduced the use of the memory profiler in the Android profiler to view the Android heap situation.
For example, what objects are there in the Android heap and what are the references of these objects.
But we still face a relatively serious challenge: whether it is an app developer or a memory analyst, there are a lot of objects in the heap, not only Android native classes, but also classes used by third-party libraries. During use, these classes may also confuse memory analysis because of their large shallow size or retained size.
In order to solve such a problem, we prefer to perform differential comparisons through heaps at different time points. That is, the heap heap1 generated at time t1 and the heap heap2 generated at time t2 are compared with each other.
To this end, we will introduce MAT, an important memory analysis tool in Java development.
Preparation before using MAT
In the previous article, we used AS to capture the heap, now we need to export it and use it on the MAT tool. As shown below:
Next, the format of the heap dump saved by Android is converted to meet the needs of MAT. The tools for converting formats are in the Android SDK. as follows:
/Users/biaowan/Library/Android/sdk/platform-tools/hprof-conv ./mat/memory-test_malloc_int\[\].hprof mat_test1.hprof
Use of MAT
After opening MAT, go to the menu bar->File->Open File. Then select the mat_test.hprof file you just converted. As shown below
It can be seen that the main interface displays an overview interface, which describes the specific details in English and will not be repeated. The eight markers in the above image are explained below.
-
Mark 1: Open the overview interface. That is the main interface above.
-
Mark 2: Open the distribution of objects in the current heap, sorted by class name by default. You can perform corresponding operations by right-clicking. The meaning of each operation has been marked. As shown below
-
Mark 3: Display all dominator trees in this heap (Note: dominator tree, has been introduced in the previous article: How android analyzes the memory of the application (16) - use AS to view the Android heap: http://t . csdn.cn/GTWpR ). How should each object view its corresponding dominator tree. See the right-click instructions corresponding to mark 2.
-
Mark 4: Open Object Qurey Language, similar to using SQL statements to query. Because the menu functions provided by MAT are fully sufficient for Android use, this article will not introduce them again.
-
Marker 5: Display the thread name, stack, local variables, etc. But Android does not provide this function, so it cannot be used
-
Mark 6: Print various reports, as marked below
-
Mark 7: This is the various operations supported by the right click in Mark 2. See Mark 2 for details.
-
Mark 8: Search button, you can search by address
In order to explain in detail how to operate MAT, the following will use various questions as templates to introduce the operation process in detail.
Question 1: How to check what objects a certain class has
- Click on marker 1 to open a list of all classes.
- In the first line, type the class you want to find, or sort and filter by different sizes
- Select the class, then right-click and select List Objects. Then list each object according to your needs
Question 2: How to check the reference chain from an object to the GC root
- Select an object, right-click and select Paths to GC root
- Select exclude all xxx references again
It can be seen that the entire reference chain is clear and clear, and is not included in the drawing instructions.
Question 3: How to view the Dominator tree of an object
- Select the object, right-click and select Java Basics
- Check Open in Dominator tree again
- In the pop-up box, select finish. Sort by object by default
From the figure, you can see that the TaskRunable object directly controls two objects, an int array and a weak reference.
Question 4: How to check the direct ruler of an object
- Select the object, then right-click and select immediate dominator
- In the pop-up box, select finish
You can see that the direct controller of the TaskRunable object we selected is a Task object
Question 5: How to check the class loader and whether the same class is loaded repeatedly
- Click mark 1 to open the overview interface
- Scroll the interface to the bottom
- Select Duplicate classes
Question 6: How to check the part of the heap that takes up the most memory
- Click mark 1 to open the overview interface
- Scroll to the bottom
- Select Top cosumer
As you can see from the figure, the parts that occupy the most memory are listed according to objects, classes, class loaders, and package names.
Question 7: How to view the heap report
- Click mark 6. Select Heap dump overview
- In the report, click table of content to view the table of contents (this field, at the bottom of the report)
You can also directly view the objects that occupy the most memory.
Question 8: How to conduct a leak check
- Click on mark 6 and select Leak Suspect
As you can see from the picture, there are three suspects. Scroll down and you can see the details of the three suspects, as follows
In the figure, the Task class is briefly explained, with 2100 instances, accounting for 29.51% of the content. Click details and it will display the corresponding reference chain path. The entire reference chain of the GC root can be clearly seen.
Perform differential analysis on multiple Heaps to find memory problems
In order to walk through step by step, how to use multiple heaps for differential analysis, we choose the example in Solution 2 of the previous article: How android Analyzes Application Memory (16)——Use AS to view the Android heap: http://t . csdn.cn/JYGFC . Then at two different times in the same process, different heaps are selected, called as_heap1.hprof and as_heap2.hprof.
Scenario 1: MAT automatically analyzes memory leaks between two heaps
-
According to the hprof-conv tool mentioned above, convert as_heap1.hprof and as_heap2.hprof to mat_heap1.hprof and mat_heap2.hprof respectively. Then open it with mat tool.
-
Open the overview operation bar of the second heap, which is marked 1. Scroll to the bottom
-
选择Leak suspects by Snapshot comparision.
-
In the pop-up box, select mat_heap1.hprof. Then click finish. Let mat_heap2.hprof and mat_heap1.hprof do differential analysis, and then give a report as follows (you need to wait for a while)
As can be seen from the figure, the com.example.test_malloc.Task object is suspected to be leaked. It has 4900 objects, accounting for 49.26% of the entire heap. Click details to see the reference chain, as shown below
As you can see from the figure, the Task is held by the listener of the DeviceManager, causing the GC to be unable to recycle it. So the memory leak point was found.
Scenario 2: Manual analysis when automatic analysis cannot be performed
When the interval between two heap heaps is short and the leaked object occupies a smaller space in the entire heap, mat cannot perform automatic analysis at this time. At this point we can analyze manually.
Next, we use two heaps with smaller time intervals, called mat_heap3.hprof and mat_heap4.hprof respectively.
Note: mat_heap3.hprof and mat_heap4.hprof are two heaps that are re-fetched with AS at a close time interval.
-
Use mat to open mat_heap3.hprof, and mat_heap4.hprof
-
According to question 6, output the part that consumes the most memory. Below is the report of mat_heap3.hprof.
From this, we see that the primary object that occupies the largest amount of memory is the int array. Next, we manually analyze the gap between the int arrays in the two heaps - that is, which int arrays mat_heap4.hprof has more than mat_heap3.hprof
-
Click on the statistics of mat_heap3.hprof, which is marked 2. Then select int[]. Right click to list all objects. As shown below
-
Click the operation history bar, right-click list_objects... and then click add to compare basket. As shown below
-
Because we need to compare the int[] status of the two heap heaps, after selecting mat_heap4.hprof, follow steps 3 and 4 to do the same operation. There will be two objects that need to be compared in the compare basket window. Then click the exclamation mark to start comparing. as follows:
Perform a simple sorting of the test results, shallow_heap #1 in ascending order. You can display objects that are not in heap3 but are in heap4. This is also the extra int array object in the heap between the time when heap3 is fetched and the time when heap4 is fetched. For the 10 objects in the front row.
According to the previous question 2, you can check its reference chain to analyze who holds it and why it has not been released.
In step 2, the output top consumer has other objects besides the int array, so follow steps 3, 4, and 5 to compare the two heaps. We have taken int[] as an example and explained it in detail, so we will not compare them one by one.
In addition to using top comsumer to assist in locating objects that need to be compared, you can also compare any suspected objects. The steps are exactly the same.
At this point, the introduction to the use of MAT is completed.
MAT makes up for the following shortcomings of AS in memory analysis:
- Unable to customize Retained Set (this is useful for large applications)
- Unable to perform address lookup
- Unable to compare between heaps
- Unable to sort as desired
- Unable to filter as needed, etc.
Although MAT is powerful enough, there is still a memory problem that remains unresolved-how can we know which thread triggers these memory leaks, and what kind of call stack do they have?
In multi-threaded programming, the leakage of objects may be unreasonable references between objects, or unreasonable logic between threads, such as unreasonable production threads and consumer threads, etc. MAT cannot solve the memory leak caused by Android threads.
Next, please look forward to how to use tools to find this kind of memory leak caused by multi-threading.