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