Use of memory analysis tools

Shallow Size和Retained Size

Shallow Size

Shallow Size refers to the size of the memory occupied by the object itself, excluding the objects it references .

For objects of non-array type , its size is the sum of the size of the object and all its member variables . Of course, there will also be some data storage units of java language features.

For objects of array type, its size is the sum of the sizes of the array element objects (determined by the object type and the length of the array).

Retained Size

Retained Size =  current object size + the sum of the sizes of objects that the current object can directly or indirectly reference . (The meaning of indirect reference: A->B->C, C is an indirect reference).

In other words, Retained Size is the total amount of memory that can be released from the Heap after the current object is GCed .

However, when releasing, it is necessary to check the objects directly or indirectly referenced by GC Roots, they will not be currently Garbage for the time being.

Look at the picture to understand the Retained Size

Retained Size

In the above figure, GC Roots directly reference two objects, A and B.

Retained Size of A object=Shallow Size of A object.

Retained Size of B object = Shallow Size of B object + Shallow Size of C object

The D object is not included here because the D object is directly referenced by the GC Root .

What if GC Roots don't refer to D objects?

At this point, the Retained Size of the B object = the Shallow Size of the B object + the Shallow Size of the C object + the Shallow Size of the D object.

GC Roots

When the GC finds that an object cannot be accessed through any reference chain, the object will be recycled. GC Roots is the starting point for analyzing this process. Usually GC Roots are objects on the current thread's call stack (such as method parameters and local variables), or the thread itself, or classes loaded by the system class loader and live objects retained by Native code (native code).

memory analysis

1. Observe Heap (dynamic)

In DDMS (Dalvik Debug Monitor Server), click the heap button to update statistics.

We mainly focus on two data:

  • Heap Size The size of the heap. When the resources increase and the free space of the current heap is not enough, the system will increase the size of the heap. If it exceeds the upper limit (such as 64M, depending on the platform and specific model), it will be killed.

  • The allocated size in the Allocated heap, which is the memory size actually occupied by the application. After the resource is reclaimed, this data will become smaller

View the heap data before and after the operation to see if there is a memory leak

2. Use MAT (Memory Analyzer Tool) to analyze the memory heap (static)

The JVM can record part of the running state of the system when the problem occurs, and store it in the heap dump file, which provides an important basis for us to analyze and diagnose the problem.

DDMS can dump the current memory into a file in hprof format, and MAT will give easy-to-read information after reading this file.

You can click the Leak Suspects menu item on the toolbar to generate a memory leak analysis report, or you can directly click the Reports->Leak Suspects link below the pie chart to generate a report.

Analytical Trilogy

Usually we will use the following "three steps" to analyze the memory leak problem:

  • First, get an overall picture of the state of the system's memory at the time of the problem.

  • The second step is to find the culprit most likely to cause the memory leak, usually the object that consumes the most memory.

  • Next, go further to check the specific situation of this large memory consumer to see if there is any abnormal behavior.

2.1 Leak Suspects

Leak Suspects will show where MAT thinks there may be memory leaks, generate a memory leak OverView interface, and get an overall impression of the memory state.

Analyze the cause of memory leaks.

2.2 Histogram

Histogram: 列出内存中的对象,对象的个数及大小。

它按类名将所有的实例对象列出来,可以点击表头进行排序,在表的第一行可以输入正则表达式来匹配结果。

2.3 Dominator Tree

Dominator Tree (支配树):列出最大的对象以及其依赖存活的Object (大小是以Retained Heap为标准排序的)

Retained Set指的是这个对象本身和他持有引用的对象以及这些引用对象的Retained Set所占内存大小的总和,官方的图解如下所示。

从图中可以看出E的Retained Set为E和G。C的Retained Set为C、D、E、F、G、H。

MAT所定义的支配树就是从上图的引用树演化而来。在引用树当中,一条到Y的路径必然会经过X,这就是X支配Y。X直接支配Y则指的是在所有支配Y的对象中,X是Y最近的一个对象。支配树就是反映的这种直接支配关系,在支配树中,父节点直接支配子节点。下图就是官方提供的一个从引用树到支配树的转换示意图。

C直接支配D、E,因此C是D、E的父节点,这一点根据上面的阐述很容易得出结论。C直接支配H,这可能会有些疑问,能到达H的主要有两条路径,而这两条路径FD和GE都不是必须要经过的节点,只有C满足了这一点,因此C直接支配H,C就是H的父节点。通过支配树,我们就可以很容易的分析一个对象的Retained Set,比如E被回收,则会释放E、G的内存,而不会释放H的内存,因为F可能还引用着H,只有C被回收,H的内存才会被释放。

这里对支配树进行了讲解,我们可以得出一个结论:通过MAT提供的Dominator Tree,可以很清晰的得到一个对象的直接支配对象,如果直接支配对象中出现了不该有的对象,就说明发生了内存泄漏。

2.4 Top Consumers

Top Consumers: 通过图形列出最大的object。

通常,Histogram和 Dominator Tree是最常用的。

2.5 outgoing references和incoming References

outgoing references:表示该对象的出节点(被该对象引用的对象)。

incoming references:表示该对象的入节点(引用到该对象的对象)。

2.6 OQL语句查询

OQL全称为Object Query Language,类似于SQL语句的查询语言,能够用来查询当前内存中满足指定条件的所有的对象。它的查询语句的基本格式为:

SELECT * FROM [ INSTANCEOF ]   <class_name> [ WHERE <filter-expression>]

在Eclipse Memory Tool 上,按OQL,输入select * from instanceof android.app.Activity, 这个指令可以找所有在系统上是android.app.Activity的instance。

关于OQL语句有很多用法,具体可以查看官方文档【http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.mat.ui.help/reference/oqlsyntax.html】。

如果在object的旁带有“Unknown”的话,那object是可以被Gargage Collect的。要看其他的object是什么原因不可以被Gargage Collect 的话,可以在那个object上right-click,然后选Path to GC Roots, exclude all phantom/weak/soft etc. references。 (这个选项排除了虚引用、弱引用和软引用,这些引用都是可以被VM查到的,所以是可以Gargage Collect的。)

The meaning of this$0 in the result is a reference to the outer class that is automatically reserved by the inner class.

3. Native memory location method

Debugging application local memory leaks is the same as Java layer memory leaks. It is impossible to accurately determine which code has a memory leak. You can only locate the suspected memory leak point, which needs to be determined in combination with the code.

Like analyzing the heap file at the Java layer, start with the code segment with larger memory allocation, and combine the allocation path and the actual code to determine whether there is a memory leak.

The specific methods are:

Method 1: Debug the level of the log

#adb root #adb shell setprop libc.debug.malloc 40 [Default is 0]

Set the process you want to debug #adb shell setprop libc.debug.malloc.program mm-qcamera-daemon

optional configuration items #adb shell setprop libc.debug.malloc.minalloclim 10240 [Default is 10KB; values are in Bytes]#adb shell setprop libc.debug.malloc.maxprocsize 31457280 [Default is 30 MB; values are in Bytes]

Restart the framework layer #adb shell stop #adb shell start

or restart the process #adb shell kill <pid_of_mm-qcamera-daemon>

Send debug signal to start crawling #adb shell kill -28 <pid_of_mm-qcamera-daemon>

debug log level #adb root #adb shell setprop libc.debug.malloc 40 [Default is 0]

Set the process you want to debug #adb shell setprop libc.debug.malloc.program mm-qcamera-daemon

optional configuration items #adb shell setprop libc.debug.malloc.minalloclim 10240 [Default is 10KB; values are in Bytes]#adb shell setprop libc.debug.malloc.maxprocsize 31457280 [Default is 30 MB; values are in Bytes]

Restart the framework layer #adb shell stop #adb shell start

or restart the process #adb shell kill <pid_of_mm-qcamera-daemon>

Send debug signal to start crawling #adb shell kill -28 <pid_of_mm-qcamera-daemon>

Method Two:

adb shell setprop libc.debug.malloc 1

adb shell stop

adb shell start

adb shell am dumpheap -n

You will get a .hprof file, which needs to be analyzed manually.

The upper part of the file is the code segment of memory allocation, sorted by memory allocation size, and the lower part is the memory allocation image of the process.

Method 3: Use DDMS

adb shell setprop libc.debug.malloc 1

adb shell stop

adb shell start

Then there is a menu of Native Heap in DDMS, you can get the corresponding debugging data

Reference link

The use of memory analysis tool MAT

Heap dump file analysis using Eclipse Memory Analyzer

Java program memory analysis: use the mat tool to analyze memory usage

The use of memory analysis tool MAT


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325192044&siteId=291194637