转自:http://blog.sina.com.cn/s/blog_606334a20100goei.html
更详细的讲解请看:http://blog.csdn.net/luoshengyang/article/details/6664554
ashmem是android的内存分配/共享机制,在dev目录下对应的设备是/dev/ashmem,相比于传统的内存分配机制,如malloc、anonymous/named mmap,其好处是提供了辅助内核内存回收算法的pin/unpin机制。
如果不使用ashmem驱动,并且舍弃pin/unpin语义,那么模拟ashmem的语义还是很简单的。首 先,ashmem_create_region可以为进程创建一个唯一的文件(如进程名+时戳),打开,然后返回这个文件的fd;接着应用程序可以进性一 般的mmap操作了。如果不使用ashmem_create_region接口函数,那么使用anonymous的mmap就可以了,但这种方式属于正在 被丢弃的方式,而且并不是所有的系统都支持,比如Macos就不支持。
Android ashmem 语义的实现
ashmem非常象是anonymous mmap,这或许是它的名字的由来吧。网上有人问pin和unpin到底是做什么用的,似乎没人回答。简单的回答是:没什么用。深沉点的回答是:可以用来更有效地使用内存。具体讲,当你觉得用ashmem分配的空间有部分似乎不大用得着时,你可以unpin这一块空间,unpin后,内核可以把它对应的物理页面回收,挪作他用。你并不用担心以后进程对unpin的空间的访问,因为回收了的内存,你还可以再次获得(通过缺页handler),因为unpin操作并不改变已经mmap的地址空间。所以说,pin/unpin纯粹是内核内部的操作,不影响上层应用的语义。
如果不用ashmem驱动,不考虑pin/unpin语义,并且考虑到现有API的持续性(ashmem_create_region等),实现ashmem的语义虽然概念上不难,但还是有一些细节需要注意。
首先,ashmem不是用于进程间共享数据的,这是由驱动实现决定的。驱动把ashmem分配的地址空间赋给file结构的private,这就排除了进程间共享的可能性。
其次,ashmem的作用等同于anonymous mmap,纯粹作分配空间用,你打开多少次/dev/ashmem设备(并mmap),你就获得多少次(不同的)空间。这在同一个进程也是一样的。这一点很重要。
举例来说:
fd1 = open("/dev/ashmem", O_RDWR);
addr1 = mmap(0, size, ..., fd1, ...);
fd2 = open("/dev/ashmem", O_RDWR);
addr2 = mmap(0, size, ..., fd2, ...);
即使在同一个进程内,addr1和addr2也是不同的。用/dev/zero达不到这个效果,普通文件也不行。
所以,在使用普通文件模拟ashmem行为时,必须给每个文件起唯一的名字。这个技术可有很多选择,比如使用开机后经历的时间作为文件名的一部分。