Android : How to analyse the native heap dump?

懵懂的女人 提交于 2019-11-29 08:51:04
fadden

The data is being generated by the dumpNativeHeap() function in android_os_Debug.cpp. Each entry is one allocation record, which contains:

  • The "zygote child" flag: z 0 means the allocation was performed in the zygote process, z 1 means it happened in a child of zygote (i.e. an app process after the fork()). This is useful for determining whether a particular allocation might be shared between multiple processes by virtue of copy-on-write.
  • The size of the allocation, in bytes.
  • The number of allocations with the exact same size and backtrace.
  • The backtrace addresses (up to 32).

The addresses aren't meaningful without a copy of /proc/<pid>/maps to see what binaries were mapped where, so a copy is included at the end.

The basic tool for converting binary + address to symbol is addr2line. You need to subtract the base address of the library from the address in the stack trace to get the library offset.

There's an easier way. The same mechanism that is used to generate these heap dumps can also be used to feed the DDMS Native Heap Tracker. This provides a full UI for browsing the contents of your native heap. You can find more information about it here and here.

FWIW, here's an example of doing it the "hard way". I dumped the heap of the Calendar app and saw this line:

z 1  sz    49152  num    1  bt b5aac102 b5aac2f6 b6f8599a b5a5e946 b5a3f268 b6f8d6a0 b6f8b83e

The relevant lines from the maps entry are:

b59ea000-b5a92000 r-xp 00000000 b3:19 817        /system/lib/libdvm.so
b5a9f000-b5ae0000 r-xp 00000000 b3:19 782        /system/lib/libc_malloc_debug_leak.so
b6f78000-b6fbf000 r-xp 00000000 b3:19 780        /system/lib/libc.so

The base address of the library must be subtracted from the address in the backtrace. You figure out what library it's in by finding the maps entry with an address range that contains the backtrace address. Working from left to right (top of the call stack to the bottom):

b5aac102 - b5a9f000 = d102
addr2line -C -f -e [...]/symbols/system/lib/libc_malloc_debug_leak.so d102
--> leak_malloc (malloc_debug_leak.cpp:283)

b5aac2f6...
--> leak_calloc (malloc_debug_leak.cpp:338)

b6f8599a - b6f78000 = d99a
addr2line -C -f -e [...]/symbols/system/lib/libc.so d99a
--> calloc (malloc_debug_common.cpp:231)

b5a5e946 - b59ea000 = 74946
addr2line -C -f -e [...]/symbols/system/lib/libdvm.so 74946
--> compilerThreadStartup (Compiler.cpp:434)

b5a3f268...
--> internalThreadStart(void*) (Thread.cpp:1752)

...and so on. This trace corresponds to a line in dalvik/vm/compiler/Compiler.cpp:

pJitTable = (JitEntry*)
            calloc(gDvmJit.jitTableSize, sizeof(*pJitTable));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!