android memory share 涉及模块: driver/ libcutils/ cpp端封装/java 端封装
1 driver
基于tmpfs实现的ashmem驱动程序,负责内存的分配和管理。 对应的misc device节点是/dev/ashmem; 提供的接口主要有: init:设备初始化 open:打开设备 release:设备对应的内存释放: mmap:内存映射 ioctl(pin/unpin):内存锁定和解锁
driver 作用: 使用tmpfs系统,读写速度快,将部分memory 映射到文件结构体上,文件结构体对应的文件描述符,这样提供出去文件描述符给userspace;使用端就可以使用文件描述符fd去mmap到自己的进程中,使用端就可以访问该共享内存。
linux 内核分配的内存才可以使用共享,fd可以在binder 中传递,binder拿到server端的fd后,binder driver也是linux 内核的逻辑,可以使用fd再拿到对应的文件结构体,然后在client进程中创建一个新的指向特定文件结构体的文件描述符fd。另一个进程就可以使用这个fd再mmap到自己的虚拟地址中去访问,这样就实现了内存快的共享。
2 libcutils
封装了ashmem driver的操作: 提供了API: ashmem_valid:确认文件描述符是指向shared memory ashmem_create_region:创建shared memory,需要指定name和size ashmem_set_prot_region:设置shared memory的mask,read/wirte/exec ashmem_pin_region: 锁定某小块memory(android Q后废弃) ashmem_unpin_region: 解锁某小块memory(android Q后废弃) ashmem_get_size_region:获取shared memory的大小
另外 libcutils 中会做一些限制和检查, 限制vendor fd和system fd的共享内存; 检查错误异常,检查fd的有效性 API转化:pin/unpin/set_prot -->ioctl
android R这边有两个逻辑:memfd和ashmemfd, 导致call API的不同,可能对应的driver 不同; 需要再确认下
libcutils作用: A 封装driver 接口,减少与driver解耦合, B 提供so 包,方便其他地方引用 C 封装一套统一的接口,可以修改内部实现,但上层功能可以不用修改
3 cpp wrapper
因为shared memory是实现进程间共享内存的作用,cpp wrapper不仅提供了server端的创建shared memory的封装类MemoryHeapBase,还提供了client端使用的封装类IMemory:
MemoryHeapBase frameworks/native/libs/binder/include/binder/MemoryHeapBase.h frameworks/native/libs/binder/MemoryHeapBase.cpp 封装了libcutils的API到cpp class中,构造函数中就会ashmem_create_region和mmap创建一块size大小的shared memory。 提供的API有: getHeapId: return fd getBase: return mBase 映射到进程中的虚拟地址 getSize: 大小size getFlags: 访问保护位
IMemory: frameworks/native/libs/binder/include/binder/IMemory.h frameworks/native/libs/binder/IMemory.cpp MemoryHeapBase的client端实现上面的四个API,同时会判断是否有做内存映射,并保证只映射一次; 因为client可能有在一个进程中有多个实例,但server端的共享内存可能在client 进程中只需要映射一次。
还提供一个MemoryBase,是对MemoryHeapBase的封装,提供了访问shared memory的部分地址。 frameworks/native/libs/binder/include/binder/MemoryBase.h frameworks/native/libs/binder/MemoryBase.cpp
4 java wrapper
MemoryFile /SharedMemory
frameworks/base/core/java/android/os/SharedMemory.java frameworks/base/core/java/android/os/MemoryFile.java frameworks/base/core/jni/android_os_SharedMemory.cpp frameworks/base/core/jni/android_os_MemoryFile.cpp 它是使用jni的方式透过libcutils创建和使用shared memory。
SharedMemory nCreate :ashmem_create_region nGetSize : ashmem_get_size_region nSetProt :ashmem_get_size_region
使用下面两个方法将cpp fd与java FileDescriptor沟通建立连接 jniCreateFileDescriptor jniGetFDFromFileDescriptor
|