Detailed explanation for profile from "adb shell dumpsys meminfo my-app-name"?

user1802093 picture user1802093 · Nov 6, 2012 · Viewed 15.8k times · Source

Can anyone give me a detailed explanation about the profile gotten by adb shell dumpsys meminfo my-app-name?

The result is just as below as it mentioned in How do I discover memory usage of my application in Android?:

** MEMINFO in pid 890 [process-name] **
                    native   dalvik    other    total
            size:    10940     7047      N/A    17987
       allocated:     8943     5516      N/A    14459
            free:      336     1531      N/A     1867
           (Pss):     4585     9282    11916    25783
  (shared dirty):     2184     3596      916     6696
    (priv dirty):     4504     5956     7456    17916

 Objects
           Views:      149        ViewRoots:        4
     AppContexts:       13       Activities:        0
          Assets:        4    AssetManagers:        4
   Local Binders:      141    Proxy Binders:      158
Death Recipients:       49
 OpenSSL Sockets:        0

 SQL
            heap:      205          dbFiles:        0
       numPagers:        0   inactivePageKB:        0
    activePageKB:        0

What does the each column (native, dalvik, other, total) mean? especially what's the "other" column (I can't figure out what's that besides native and dalvik)? It would be great if someone can give a concrete example to elaborate about this. e.g. I have an app A. A has its own object obj_private and its own native library lib_private. Besides, A references some object of Android framework obj_shared and some native lib of Android framework lib_shared. And obj_shared reference some native lib of Android lib_shared_indirect. For this case, can I say those?

  1. The "total size" equals all memory used by "obj_private + lib_private + obj_shared + lib_shared + lib_shared_indirect".
  2. The "private dirty" equals memory dirtied by "obj_private + lib_private"

The reason we want to make clear about this is: there are some unusual runtime-memory increase of our latest version app compared to previous version. And when I used the dumpsys meminfo, I found the columns "native" and "other" increased dramatically. But the change of the new version is only related to java and there is no explain about the "other" column. I googled this and found no document. I also tried to read the source code of the adb. But I found it's easy to get lost in the source code for novice like me. So I post this question here in case that some one can help.

Answer

hackbod picture hackbod · Nov 12, 2013

We now have more documentation covering RAM use in Android that goes into some detail about what different RAM numbers mean: Managing Your App's Memory. In particular, have a look at the middle of the page here that discusses key parts of the meminfo dump: Investigating Your RAM Usage.

It looks like your meminfo output is from a fairly old version of Android, before we could identify many of the different types of allocations. To map what you are seeing to the current documentation, just consider "other" to be everything that the modern dump shows besides the native and dalvik sections. In your dump, I believe your dalvik section is actually the modern "Dalvik Heap" and "Dalvik Other" put together.

As far as the native and other sections increasingly after only a change in the Java code, yes this can certainly happen. A number of parts of the Android Java API sits on top of native allocations, and can also cause other allocations. The classic example of this would be bitmaps on Gingerbread and earlier, where the data for the bitmap was a native allocation rather than being an array allocations in the Java heap as it is today.

Your increased other allocations can be due to a number of things as you will see listed in the more recent versions of the data -- the memory backing cursors, shared memory areas from ashmem, devices allocating things for you such as graphics textures, etc. There are so many things it can be hard to say what might be going on, which is why the report is more detailed these days. (And even there, we still have a number of things that get collapsed in to unknown.)

For debugging this, you probably want to look at your Java heap for leaked objects. Since the actual allocation for the object is not in the Java heap, this can be tricky of course. I'd suggest taking a heap dump early in your app, do whatever you do that causes its RAM footprint to increase, take a heap dump after that, and look for what object counts have increased. The referenced documentation shows how to compare heap dumps with MAT.

Also when you are looking at your Java heap just as a general analysis (except when doing diffs), always be sure to follow the instructions there for stripping out the zygote part of the heap. As the documentation mentions, every process has a large number of allocations from zygote, but these are shared across all processes so not generally relevant for heap analysis. I very often see people concerned because they see a lot of very large bitmaps in their app that the system seems to have allocated on them, and think that is the major thing using RAM in their app, when it is not, it is just the shared allocations from zygote.