一、Binder 缓冲区为什么限制为 1MB?
1. 内核内存保护
-
Binder 缓冲区位于 Linux 内核空间(非用户空间)
-
内核内存是全局共享资源,过度消耗会导致:
-
系统级内存不足(OOM)
-
内核崩溃(影响所有进程)
-
-
1MB 是经验值平衡点:满足多数 IPC 需求 + 避免内核风险
2. 防御恶意攻击
-
防止恶意应用通过超大 Binder 调用:
-
耗尽内核内存
-
发起拒绝服务攻击(DoS)
-
-
限制单次传输大小可提升系统健壮性
3. 性能优化
-
小缓冲区减少内存拷贝开销(Binder 默认使用一次拷贝)
-
避免大内存分配导致的线程阻塞(发送/接收方可能被挂起)
4. 历史硬件限制
-
早期 Android 设备内存仅 128MB-512MB
-
1MB 在当时已占内核内存的显著比例(约 0.2%~0.8%)
-
虽现代设备内存更大,但保持兼容性
二、为什么 Bundle 数据存储在 Binder 缓冲区?
1. 跨进程传输需求
-
Bundle 是 Android 组件间(如 Activity/Service)传递数据的通用容器
-
当组件位于不同进程时(如启动其他 App 的 Activity):
java// 示例:启动其他进程的 Activity Intent intent = new Intent(); intent.setComponent(new ComponentName("com.other.app", "MainActivity")); Bundle bundle = new Bundle(); bundle.putString("key", "value"); intent.putExtras(bundle); startActivity(intent); // 触发 Binder IPC
-
必须通过 Binder 缓冲区传递数据
2. 同步通信模型
-
Binder 采用同步调用(发送方阻塞等待结果)
-
Bundle 作为调用参数需立即可用
-
存储在内核缓冲区可避免:
-
二次序列化开销
-
用户空间到内核空间的额外拷贝
-
3. 安全隔离
-
内核缓冲区提供安全边界:
-
数据隔离:进程无法直接访问对方内存
-
权限检查:Binder 驱动可验证 IPC 权限
-
4. Parcel 的优化设计
-
Bundle 内部使用
Parcel
序列化 -
Parcel
直接操作 Binder 缓冲区:java// 简化版 Parcel 写入流程 public void writeToParcel(Parcel dest, int flags) { dest.writeInt(code); // 直接写入 Binder 缓冲区 dest.writeBundle(data); }
-
优势:零拷贝(数据直通内核)