本系列:

Android-Binder进程间通讯机制-多图详解

一次Binder通信最大可以传输多大的数据?​​​​​​​

关于Binder (AIDL)的 oneway 机制

前言

在第六章中,我通过匿名共享内存的方式解决Binder通信是无法传递大数据的问题,一次Binder通信最大可以传输是1MB-8KB(PS:8k是两个pagesize,一个pagesize是申请物理内存的最小单元)

但是这个答案对不对呢,我只能说不准确,接下来我们来仔细研究一下:

1MB-8KB的限制来源于哪里

frameworks/native/libs/binder/ProcessState.cpp
#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)//这里的限制是1MB-4KB*2ProcessState::ProcessState(const char *driver)
{if (mDriverFD >= 0) {// mmap the binder, providing a chunk of virtual address space to receive transactions.// 调用mmap接口向Binder驱动中申请内核空间的内存mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);if (mVMStart == MAP_FAILED) {// *sigh*ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());close(mDriverFD);mDriverFD = -1;mDriverName.clear();}}
}

如果一个进程使用ProcessState这个类来初始化Binder服务,这个进程的Binder内核内存上限就是BINDER_VM_SIZE,也就是1MB-8KB。

frameworks/base/cmds/app_process/app_main.cpp
    virtual void onZygoteInit(){sp<ProcessState> proc = ProcessState::self();ALOGV("App process: starting thread pool.\n");proc->startThreadPool();}

对于普通的APP来说,我们都是Zygote进程孵化出来的,Zygote进程的初始化Binder服务的时候提前调用了ProcessState这个类,所以普通的APP跨进程上限就是1MB-8KB。

问一下自己,能否不用ProcessState来初始化Binder服务,来突破1M-8KB的限制?

答案是当然可以了,Binder服务的初始化有两步,open打开Binder驱动,mmap在Binder驱动中申请内核空间内存,所以我们只要手写open,mmap就可以轻松突破这个限制。源码中已经给了类似的例子。

frameworks/native/cmds/servicemanager/bctest.c
int main(int argc, char **argv)
{struct binder_state *bs;uint32_t svcmgr = BINDER_SERVICE_MANAGER;uint32_t handle;bs = binder_open("/dev/binder", 128*1024);//我们可以把这个数值改成2*1024*1024就可以突破这个限制了if (!bs) {fprintf(stderr, "failed to open binder driver\n");return -1;}
frameworks/native/cmds/servicemanager/binder.c
struct binder_state *binder_open(const char* driver, size_t mapsize)
{...//省略部分代码bs->fd = open(driver, O_RDWR | O_CLOEXEC);....//省略部分代码bs->mapsize = mapsize;//这里mapsize=128*1024bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);....//省略部分代码
}

难道Binder驱动不怕我们传递一个超级大的数字进去吗?

其实是我们想多了,在Binder驱动中mmap的具体实现中还有一个4M的限制 /drivers/staging/android/binder.c

static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
{int ret;struct vm_struct *area;struct binder_proc *proc = filp->private_data;const char *failure_string;struct binder_buffer *buffer;if (proc->tsk != current)return -EINVAL;if ((vma->vm_end - vma->vm_start) > SZ_4M)vma->vm_end = vma->vm_start + SZ_4M;//如果申请的size大于4MB了,会在驱动中被修改成4MBbinder_debug(BINDER_DEBUG_OPEN_CLOSE,"binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n",proc->pid, vma->vm_start, vma->vm_end,(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,(unsigned long)pgprot_val(vma->vm_page_prot));

目前的结论

  1. 通过手写open,mmap初始化Binder服务的限制是4MB
  2. 通过ProcessState初始化Binder服务的限制是1MB-8KB

再问一下自己,4M或1MB-8KB这个答案是不是正确?

我发现一处代码 /drivers/staging/android/binder.c

static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
{//省内部分代码proc->free_async_space = proc->buffer_size / 2;//这个代码引起我注意,async代码异步的意思barrier();proc->files = get_files_struct(current);proc->vma = vma;proc->vma_vm_mm = vma->vm_mm;
static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,size_t data_size,size_t offsets_size, int is_async)
{//省略部分代码if (is_async &&proc->free_async_space < size + sizeof(struct binder_buffer)) {//对于oneway的Binder调用,可申请内核空间,最大上限是buffer_size的一半,也就是mmap时候传递的值的一半。binder_debug(BINDER_DEBUG_BUFFER_ALLOC,"%d: binder_alloc_buf size %zd failed, no async space left\n",proc->pid, size);return NULL;}

为什么要做这样子的限制,我的猜想是Binder调用中同步调用优先级大于oneway(异步)的调用,为了充分满足同步调用的内存需要,所以将oneway调用的内存限制到申请内存上限的一半。

问题:一次Binder通信最大可以传输多大的数据?

再问一下自己,自己写的APP能否突破1M-8KB的限制

答案是理论上可以,但是不建议这样子操作,因为Binder驱动中并没有对open,mmap有调用次数的限制,App可以通过JNI调用open,mmap来突破这个限制,但是会对当前正在进行Binder调用的APP造成不可想象问题,当然可以先close Binder驱动。但是一旦这个APP没有Binder通信了,这个APP就不能正常使用了,APP和其他应用,AMS,WMS的交互可都是依赖于Binder通信,所以还是那句话,无Binder无Android。

一次Binder通信最大可以传输多大的数据?相关推荐

  1. Android Binder通信一次拷贝你真的理解了吗?

        Android Binder通信一次拷贝你真的理解了吗? Android Binder框架实现目录: Android Binder框架实现之Binder的设计思想 Android Binder ...

  2. Android10.0 Binder通信原理(十一)-Binder总结

    摘要:本节主要来讲解Android10.0 Binder的通信原理总结 阅读本文大约需要花费17分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...

  3. Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击

    摘要:本节主要来讲解Android10.0 Binder的数据是如何完成定向打击 阅读本文大约需要花费30分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...

  4. Android10.0 Binder通信原理(五)-Binder驱动分析

    摘要:本节主要来讲解Android10.0 Binder的驱动层分析 阅读本文大约需要花费35分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计 ...

  5. Android10.0 Binder通信原理(四)-Native-C\C++实例分析

    摘要:本节主要来讲解Android10.0 Binder的Native层实例流程 阅读本文大约需要花费35分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...

  6. Android10.0 Binder通信原理(三)-ServiceManager篇

    摘要:本节主要来讲解Android10.0 Binder中守护进程ServiceManager是如何启动.注册.获取服务 阅读本文大约需要花费35分钟. 文章首发微信公众号:IngresGe 专注于A ...

  7. Android10.0 Binder通信原理(二)-Binder入门篇

    摘要:本节主要来讲解Android10.0 Binder的设计原理,如何设计一个Binder通信 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分 ...

  8. Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要

    摘要:本节主要来讲解Android10.0 Binder.HwBinder.VndBinder的关联与各自作用 阅读本文大约需要花费10分钟. 文章首发微信公众号:IngresGe 专注于Androi ...

  9. Binder通信机制介绍

    1.Binder通信机制介绍 这篇文章会先对比Binder机制与Linux的通信机制的差别,了解为什么Android会另起炉灶,采用Binder.接着,会根据 Binder的机制,去理解什么是Serv ...

最新文章

  1. android多媒体图文混排,干货!!!Android富文本实现图文混排
  2. 数据格式之战:JSON vs XML
  3. 坐标变换,空间变换的本质
  4. 美国纽约的一个摄像头!刷新即现奇迹!
  5. JEPaas代码_((列表)输入字段值而计算
  6. JAVA中的设计模式三(策略模式)
  7. uniapp动态修改样式_uniapp样式动态绑定
  8. Ubuntu16.04 UltraEdit 安装破解使用
  9. 适用于连续资源块的数组空闲链表的算法
  10. 周鸿祎:通往伟大企业之路
  11. 共享单车需求预测问题:建模篇
  12. 初探 Yii2 的测试模式 index-test.php
  13. linux tomcat6安装及配置
  14. DNS与NS、NS记录
  15. 程序员的你不可不知的数据库northwind
  16. 4.VEH(向量化异常处理)
  17. 罗永浩被判为“老赖”最新回应:“卖艺”也要还完债,锤子科技会做下去
  18. 【小迪安全】web安全|渗透测试|网络安全 | 学习笔记-5
  19. 相似度算法--莱文斯坦距离加入同义词逻辑
  20. Thingsboard 2.5 CE版本项目结构说明

热门文章

  1. envi反演水质参数_科技前沿基于GOCI静止水色卫星数据的长江口及邻近海域Kd(490)遥感反演及其在机载激光测深预评估中的应用...
  2. OPENCV已知内参求外参
  3. HPAIC人类蛋白质图谱分类挑战赛金牌经验分享
  4. Log4J xml配置
  5. Nexenta和ParaScale发布开源存储产品
  6. Spring整合JMS(四)——事务管理
  7. Java算法试题--猜字母/杀人游戏
  8. #技术分享# “乐高”内核的诞生
  9. linux 下常见启动文件配置
  10. C#操作SQLite 报错 (Attempt to write a read-only database)