Android Performance Tuning: Write once solved OOM experience

UNCLE

OOM (Out Of Memory) is the Android application development, everyone believed that the problem encountered, and OOM stack trace in the crash log is generally no practical significance, because it is only when the memory allocation throws OOM exception, the reason stack trace and OOM this time has nothing to do. So locate and analyze multi-OOM issues will need to take some effort.

Now, I will combine an example, say something about how the positioning OOM problem.

problem

In the programmers finish the code, the basic flow test cleared, ready for release when the cloud test results is: a big wave OOM exception. I had no choice but to re-open the computer to locate the problem.
Because I am not a person to write code, so a direct look at the code a bit difficult to locate the problem, this time to get on the tool.

1. Qualitative issues

1.1 locate the problem, qualitative

This is OOM lead to a memory leak, or the application itself is poorly designed, leading to excessive memory to be loaded once, resulting in the OOM?

Method of locating the problem is very simple, look at the memory is not always growing, if memory has been growing in the use of the process, it is likely due to a memory leak.

1.2 Recommended Tools

Android Studio comes with a Memory Monitor, a very simple little tool, able to use memory in real time to show up, as simple as I think do not need to say more. As shown below:

Android Performance Tuning: Write once solved OOM experience

After playing for a few minutes, I found several problems:

1. app just started when the memory footprint is very big, because with a lot of texture (poorly designed)

2. app after entering the player interface and launch, even if the operation does not do anything, the memory has been slow growth (memory leaks)

3. app I quit again into time, memory usage has nearly doubled (memory leaks)

Among them, the problem will soon be able to guess 2, after the player MediaPlayerhas not been released, after verifying the next, resolve.

2. Improper design? optimization!

This problem is very extensive, and for example, a solid color background images would not be achieved without exceeding the pixel values ​​of the picture needs, the picture is not loaded beyond the display range, and so on.

Eventually I found a few pictures, only 1280x720, given figure is 1920x1080. At the same time a simple realization LazyLoading picture. Question 1 basic improvise to get.

3. Memory leak?

If in the course of the memory curve it has been a rising trend, which is likely a memory leak.

3.1 Viewing information heap

Android SDK toolset to provide such a tool: Device Monitor. Use as follows:

1. Open Device Monitor Android
2. Select the process you want to debug
3. Click the button Update Heap

FIG substantially as follows:

Android Performance Tuning: Write once solved OOM experience

We can see the basic stack, as well as an overview of the objects in the heap.

3.2 Leak View Activity

Many common memory leaks are due to be released Activity object can not caused, by the following adb command can quickly navigate to this question:

adb shell dumpsys meminfo <package_name>

The results obtained are as follows:

** MEMINFO in pid 9953 [com.google.android.gm] **
                 Pss     Pss  Shared Private  Shared Private    Heap    Heap    Heap
               Total   Clean   Dirty   Dirty   Clean   Clean    Size   Alloc    Free
              ------  ------  ------  ------  ------  ------  ------  ------  ------
  Native Heap      0       0       0       0       0       0    7800    7637(6)  126
  Dalvik Heap   5110(3)    0    4136    4988(3)    0       0    9168    8958(6)  210
 Dalvik Other   2850       0    2684    2772       0       0
        Stack     36       0       8      36       0       0
       Cursor    136       0       0     136       0       0
       Ashmem     12       0      28       0       0       0
    Other dev    380       0      24     376       0       4
     .so mmap   5443(5) 1996    2584    2664(5) 5788    1996(5)
    .apk mmap    235      32       0       0    1252      32
    .ttf mmap     36      12       0       0      88      12
    .dex mmap   3019(5) 2148       0       0    8936    2148(5)
   Other mmap    107       0       8       8     324      68
      Unknown   6994(4)    0     252    6992(4)    0       0
        TOTAL  24358(1) 4188    9724   17972(2)16388    4260(2)16968   16595     336

 Objects
               Views:    426         ViewRootImpl:        3(8)
         AppContexts:      6(7)        Activities:        2(7)
              Assets:      2        AssetManagers:        2
       Local Binders:     64        Proxy Binders:       34
    Death Recipients:      0
     OpenSSL Sockets:      1

 SQL
         MEMORY_USED:   1739
  PAGECACHE_OVERFLOW:   1164          MALLOC_SIZE:       62

Which ViewRootImpl, Activities, AppContexts number of very worthy of attention.
For other meanings of output, see the developer docs

3.3 取heap dump

After determining the basic memory leak, you need to locate specific objects which leak, good positioning of the relevant code, this time we can analyze the heap dump.

heap dump is a snapshot of heap memory, what it can be used to analyze specific memory in the end there.

First, we need to derive a Device Manager heap dump, shown in FIG.

Android Performance Tuning: Write once solved OOM experience

Then converted to java dump, with the Eclipse Memory Analyzer Tool (MAT) were analyzed.

With platform-tools in the hprof-conv be converted:

hprof-conv heap-original.hprof heap-converted.hprof

After the conversion is complete, we can use the MAT to open the analysis.

4. Eclipse Memory Analyzer Tool (MAT)

When we open the dump with MAT, see the basic interface is as follows:

Android Performance Tuning: Write once solved OOM experience

Here are a few concepts you need to know:

1. Shallow Heap & Retained Heap

  • Shallow Heap的大小就是对象所占的内存空间,一般一个Object持有一个引用会需要32或者64bit的空间(取决于JVM)。
  • 由于A对象持有B对象引用会导致B对象在GC中不会被销毁,所以由于被对象直接或者间接持有引用而不会被释放的对象的占用的内存总和,就是Retained Heap。
  • 简单来说,Shallow heap就是对象占用的空间,Retained Heap就是假如对象被释放,连带能够释放出来的空间。

2. Dominator Tree

  • 定义在这里。简单来说,Dominator Tree可以很好地观察Retained Heap大小。

  • 通常,在dump中查看Histogram和dominator_tree就可以看出一些端倪,例如这个例子中,histogram图中,占用内存最多的是byte[]对象,通过右键 -&gt; List object菜单,可以看到

Android Performance Tuning: Write once solved OOM experience

基本上都是Bitmap对象,而且Bitmap有重复数据:

Android Performance Tuning: Write once solved OOM experience

到这一步,可以继续追查是谁导致两份相同的数据不能得到释放,通过
右键 -&gt; Path to CG root功能,可以追查到最终是被哪个对象持有导致不能被释放,结果如下:

Android Performance Tuning: Write once solved OOM experience

到这里,问题基本就明白了:

DBHelper是一个单例静态对象,这个对象会持有一个Context对象,在代码中被当成Context传入DBHelper的是一个Activity对象,所以这个Activity不会被释放;当这个Activity被销毁重建时,新的Activity会重新加载ContentView,而老的Activity所持有的整个View的树全部不会被释放,同时View持有的图片也不会被释放,导致内存不够。

At this point, the whole issue has basically been found, and tell us, in single cases it is best not to hold Contextthe object, if demand requires, to see this design is reasonable, and prudent use of the time.

A common technique MAT

When analyzing memory footprint, you can usually see the most variety when occupancy Bitmapobjects, this time, if we can directly display this Bitmapcontent, you'll find it a lot easier. Here is a method to view:

See answer here on stackoverflow

end

I refer to the whole process is basically the Google official documents Investigating Your RAM Usage , this document can be read next.

Well, the article written here is over, if you think the article is well written give a praise chant? If you think there need to be improved, please give me a message. Will be serious inquiry, insufficiently corrected. Thank you.

Android architects of the road is long, encourage each other with it!

Guess you like

Origin blog.51cto.com/14332859/2448290