加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Android Ashmem相关详解

发布时间:2021-11-25 17:20:26 所属栏目:PHP教程 来源:互联网
导读:基本原理 Android 的Ashmem是一种共享内存的机制,它基于mmap系统调用,不同进程可以将同一段物理内存映射到各自的虚拟地址控制,从而实现共享。 Ashmem与mmap的区别 mmap通过映射同一个普通文件实现进程间共享内存,普通文件被映射到进程地址空间后,进程可

基本原理
 
Android 的Ashmem是一种共享内存的机制,它基于mmap系统调用,不同进程可以将同一段物理内存映射到各自的虚拟地址控制,从而实现共享。
 
Ashmem与mmap的区别
 
mmap通过映射同一个普通文件实现进程间共享内存,普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read,write等操作。进程在映射空间对共享内存的改变并不直接写回到磁盘文件中,在调用munmap后才执行此操作。可以通过调用msync实现磁盘上文件内存与共享内存区的内容一致。
 
Ashmem与mmap的区别在于Ashmem与cache shrinker关联起来,可以控制cache shrinker在适当时机回收这些共享内存。
 
Ashmem的实现
 
Ashmem的源代码在mm/ashmem.c中,它通过注册Cache Shrinker回收内存,通过注册misc设备提供open,mmap等接口,mmap则通过tmpfs创建文件来分配内存,tmpfs将一块内存虚拟为一个文件,这样操作共享内存就相当于操作一个文件。
 
Ashmem用两个结构体ashmem_area和ashmem_range来维护分配的内存,ashmem_area代表共享的内存区域,ashmem_range则将这段区域以页为单位分为多个range。
 
ashmem_area有个unpinned_list成员,挂在这个list上的range可以被回收。ashmem_range有一个LRU链表,在cache shrink回收一个ashmem_area的某段内存时候,是根据LRU的原则来选择哪些页面优先被回收的。
 
Ashmem的基本结构如下图所示。
 
 
 
下面依次简单分析主要函数功能:
 
l ashmem_init
 
这是module初始化函数,Ashmem是作为一个模块实现的。该函数主要功能:
 
n 调用kmem_cache_create分别创建struct ashmem_area和structashmem_range 的slab cache
 
n 调用misc_register注册 ahsmem driver
 
n 调用register_shrinker注册Ashmem的 CacheShrinker
 
l ashmem_open
 
标准misc设备的open函数。它调用kmem_cache_zalloc分配一个 ashmem_area,并初始化各成员变量。
 
l ashmem_release
 
做与ashmem_open相反工作,释放tmpfs文件,ashmem_area及其ashmem_range。
 
l ashmem_mmap
 
mmap操作,主要就是调用shmem_file_setup从tmpfs文件系统中创建一个文件(实际上就是一段RAM)给ashmem_area用,该文件代表着这段被共享的内存。Ashmem真正实现进程共享内存的机制是靠shmem这个linux标准机制提供的。
 
l ashmem_shrink
 
即Ashmem的cacheshrink函数。它被mm/vmscan.c::shrink_slab调用,或者被用户的 ioctl
 
命令调用。这个函数从LRU链表上回收指定数目的 unpinned ashmem_range。
 
l ashmem_ioctl
 
这个函数提供ioctl 接口,它实现了如下命令:
 
 
 
l ashmem_unpin
 
unpin一段内存。实现的方法很简单,就是分配一个ashmem_range,把它挂到ashmem_area -> unpinned_list上,并加到 LRU链表上。
 
ashmem_pin
 
pin一段内存,从 ashmem_area->unpinned_list上拿下这个 ashmem_range,由此可知,被unpin的range才能被回收,pin的range则不能回收。
 
用户接口
 
Ashmem驱动创建了/dev/ashmem设备文件,进程A可通过open打开该文件,用ioctl命令ASHMEM_SET_NAME和ASHMEM_SET_SIZE设置共享内存块的名字和大小,并将得到的handle传给mmap,来获得共享的内存区域,进程B通过将相同的handle传给mmap,获得同一块内存,handle在进程间的传递可通过Binder来实现。
 
 

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读