简体   繁体   English

Android:如何分析本机堆转储?

[英]Android : How to analyse the native heap dump?

I have created a native heap dump file by using the command dumpheap -n <PID> <file> . 我已经使用命令dumpheap -n <PID> <file>创建了一个本地堆转储文件。 The file is in human readable format but contains information that is too hard to understand. 该文件为人类可读格式,但包含的信息太难理解。 How can I analyze this file and get useful information out of it? 如何分析此文件并从中获取有用的信息?

The function address are provided in the place of function names. 在功能名称的位置提供了功能地址。 The mapping is provided at the bottom of the file. 该映射位于文件的底部。 Is there any tool to map these and provide meaningful output with function/lib names instead of addresses (load the symbols for libraries/functions). 是否有任何工具可以映射这些文件,并提供具有功能/库名称而不是地址的有意义的输出(加载库/功能的符号)。 If there isn't one then how does ddms do this? 如果没有,那么ddms如何做到这一点? Also how to load the symbols to display the function names? 还有如何加载符号以显示功能名称?

Is there any way that I can compare two or more native heap dumps? 有什么方法可以比较两个或多个本机堆转储?

The dump heap file that I got looks like this 我得到的转储堆文件看起来像这样

Android Native Heap Dump v1.0 Android本机堆转储v1.0

Total memory: 13863984 Allocation records: 3108 总内存:13863984分配记录:3108

z 1 sz 8388608 num 1 bt 40afcd1a 40afbc0e 40119d30 40795210 407a9bae 407941a0 4076c264 40770b6c 407a47f4 407a481e 40786d44 407a6da6 407a800e 407a58c4 407a820a 40798ac8 40115bb4 4011530c z 1 sz 8388608 num 1 bt 40afcd1a 40afbc0e 40119d30 40795210 407a9bae 407941a0 4076c264 40770b6c 407a47f4 407a481e 40786d44 407a6da6 407a800e 407a58c4 407a820a 40798ac8 40115bb4

z 1 sz 1516906 num 1 bt 40afcd1a 40afbc0e 40119d30 400658fe 402563d8 5a400b10 5d6c3ed2 5d6c3efc 5d6c3f34 5d69d556 5d6a9de0 40794664 407aafa0 4076c264 40770b6c 407a47f4 407a481e 407af4a8 407aff8c 407678b0 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e 401de472 4005ddd2 40119ed4 Z 1 SZ 1516906 NUM 1 BT 40afcd1a 40afbc0e 40119d30 400658fe 402563d8 5a400b10 5d6c3ed2 5d6c3efc 5d6c3f34 5d69d556 5d6a9de0 40794664 407aafa0 4076c264 40770b6c 407a47f4 407a481e 407af4a8 407aff8c 407678b0 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e 401de472 4005ddd2 40119ed4

z 1 sz 262144 num 1 bt 40afcd1a 40afbc0e 40119d30 400658fe 40a14416 40a144e0 40a154a4 40a1570e 40a1d8cc 40a20d42 40a1a9e4 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 401f0c90 40762e34 40792086 4076c264 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e 401de472 4005ddd2 Z 1 SZ 262144 NUM 1 BT 40afcd1a 40afbc0e 40119d30 400658fe 40a14416 40a144e0 40a154a4 40a1570e 40a1d8cc 40a20d42 40a1a9e4 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 401f0c90 40762e34 40792086 4076c264 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e 401de472 4005ddd2

z 1 sz 262144 num 1 bt 40afcd1a 40afbc0e 40119d30 400658fe 40a14416 40a144e0 40a154a4 40a1570e 40a1d8cc 40a20d42 40a1a9e4 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 401f0c90 40762e34 40792086 4076c264 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e Z 1 SZ 262144 NUM 1 BT 40afcd1a 40afbc0e 40119d30 400658fe 40a14416 40a144e0 40a154a4 40a1570e 40a1d8cc 40a20d42 40a1a9e4 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 401f0c90 40762e34 40792086 4076c264 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e

z 1 sz 65536 num 1 bt 40afcd1a 40afbc0e 40119d30 400658fe 40a14400 40a15714 40a1d8cc 40a20d42 40a1a9e4 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 401f0c90 40762e34 40792086 4076c264 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e 401de472 4005ddd2 40119ed4 Z 1 SZ 65536 NUM 1个BT 40afcd1a 40afbc0e 40119d30 400658fe 40a14400 40a15714 40a1d8cc 40a20d42 40a1a9e4 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 401f0c90 40762e34 40792086 4076c264 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e 401de472 4005ddd2 40119ed4

z 1 sz 65536 num 1 bt 40afcd1a 40afbc0e 40119d30 400658fe 40a14400 40a15714 40a1d8cc 40a20d42 40a1a9e4 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 401f0c90 40762e34 40792086 4076c264 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e 401de472 4005ddd2 Z 1 SZ 65536 NUM 1个BT 40afcd1a 40afbc0e 40119d30 400658fe 40a14400 40a15714 40a1d8cc 40a20d42 40a1a9e4 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 40a1aa26 401f0c90 40762e34 40792086 4076c264 40770b6c 407a4aba 407ac010 4076c264 40770b6c 407a47f4 4078e676 401dd98e 401de472 4005ddd2

What are these figures indicating? 这些数字表示什么?

The data is being generated by the dumpNativeHeap() function in android_os_Debug.cpp . 数据由android_os_Debug.cpp中dumpNativeHeap()函数生成。 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 (ie an app process after the fork() ). “ zygote child”标志: z 0表示分配是在zygote进程中执行的, z 1表示分配发生在zygote的子进程中(即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). 回溯地址(最多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. 如果没有/proc/<pid>/maps的副本以查看二进制文件被映射到的位置,这些地址就没有意义,因此在末尾包含一个副本。

The basic tool for converting binary + address to symbol is addr2line . 将二进制+地址转换为符号的基本工具是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. 用于生成这些堆转储的机制也可以用于提供DDMS本机堆跟踪器。 This provides a full UI for browsing the contents of your native heap. 这提供了用于浏览本机堆内容的完整UI。 You can find more information about it here and here . 您可以在此处此处找到有关它的更多信息。

FWIW, here's an example of doing it the "hard way". FWIW,这是一个“艰难的方式”的例子。 I dumped the heap of the Calendar app and saw this line: 我转储了Calendar应用程序的堆,并看到以下行:

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 : 该跟踪对应于dalvik/vm/compiler/Compiler.cpp的一行:

pJitTable = (JitEntry*)
            calloc(gDvmJit.jitTableSize, sizeof(*pJitTable));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM