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

前言

在前面的文章中,我通过匿名共享内存的方式解决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*2
 
ProcessState::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 onZygoteIni

在 Android 系统中,Binder 通信机制是进程间通信(IPC)的核心组件之一,负责在不同进程之间传递数据Binder 通信存在默认的数据大小限制,主要是为了防止系统资源被量占用,导致性能下降或内存溢出问题。 ### Binder 数据大小限制 Binder 传输数据大小受到 `flat_binder_object` 结构和 `binder_transaction_data` 结构的限制,通常默认的最大传输数据大小为 **1MB**(具体为 1048576 字节)[^1]。这个限制是由 Android 内核中的 `binder.c` 文件定义的,主要目的是防止 Binder 通信过程中占用过内存。 ### 修改 Binder 数据大小限制的方法 要修改 Binder数据大小限制,需要对 Android 系统源码进行修改,并重新编译系统镜像。具体步骤如下: 1. 找到并修改 `binder.c` 文件中的 `BINDER_VM_SIZE` 宏定义: ```c // kernel/drivers/android/binder.c #define BINDER_VM_SIZE ((1 * 1024 * 1024) - SZ_4K) // 默认为 1MB ``` 可以将其修改为更的值,例如 2MB: ```c #define BINDER_VM_SIZE ((2 * 1024 * 1024) - SZ_4K) ``` 2. 修改完成后,重新编译 Android 内核和系统镜像。 3. 将新的系统镜像刷入设备进行测试。 需要注意的是,增加 Binder数据大小限制可能会导致内存使用增加,影响系统稳定性,因此应谨慎评估实际需求和设备性能。 ### 替代方案 如果不想修改系统源码,可以考虑使用其他 IPC 机制,例如: - 使用 `Messenger` 或 `AIDL` 接口设计时对数据进行分块传输。 - 使用共享内存(`ashmem`)结合 Binder 通信,将数据指针传递给目标进程。 - 使用 `ContentProvider` 或 `Socket` 等方式进行跨进程数据传输。 这些方法可以在不修改系统源码的前提下实现数据传输。 ### 示例代码(使用 AIDL 分块传输) ```aidl // IMyService.aidl interface IMyService { void sendData(in byte[] dataChunk); } ``` 客户端可以将数据分割为个块,逐个发送: ```java byte[] largeData = getLargeData(); int chunkSize = 1024 * 1024; // 1MB per chunk for (int i = 0; i < largeData.length; i += chunkSize) { int size = Math.min(chunkSize, largeData.length - i); byte[] chunk = new byte[size]; System.arraycopy(largeData, i, chunk, 0, size); myService.sendData(chunk); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值