Android系统内核基于Linux2.6+内核,因此,其在进程内存管理方面的很多机制和Linux是很相像的。首先,让我们来看一个典型的Android进程的内存镜像(App进程和Native本地进程略有差别,但原理是一样的):
和Linux一样,Android提供了基于/proc的“伪文件”系统来作为查看用户进程内存映像的接口(cat /proc/pid/maps)。可以说,这是Android系统内核层开放给用户层关于进程内存信息的一扇窗户。通过它,我们可以查看到当前进程空间的内存映射情况,模块加载情况以及虚拟地址和内存读写执行(rwxp)属性等。
首先我们来解读下上面的maps。
以libc.so为例:
第一列:400dd000------40142000 ,可以看出这是内存中连续的地址空间,分成了3个子空间,分为400dd000-40142000,40142000-40144000,40144000-40146000。你可能会问了,既然是加载libc.so,为什么要加载3次?好问题!
我们继续看第二列:r-xp r--p rw-p。其中r表示只读,w表示可写,x表示可执行,p表示私有(s表示共享)。让我们看一下libc.so的elf的程序头和段说明部分内容(ELF为类unix的可执行或共享镜像的格式,类似于windows PE格式,后续漫游系列详细讲解),我们可以通过Google提供的Android NDK Toolchains工具链的arm-linux-androideabi-readelf来读取(arm-linux-androideabi-readelf -a libc.so).