Binder原理详解

147 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情


1 Binder介绍

1.1 什么是Binder

Binder是一种进程间通信机制,在Android中我们所使用的Activity,Service等组件都需要和AMS(system_server) 通信,这种跨进程的通信都是通过Binder完成。

Binder在不同层面的呈现:

  • 机制:Binder是一种进程间通信机制。
  • 应用层:Binder是一个能发起通信的Java类。
  • 底层:Binder是一个虚拟物理设备驱动。

Binder通信机制架构如下所示:

1.2 多进程的作用和优势

Binder是用来做进程间通信,说明开发中会有多进程的需求,那么多进程的作用和优势是什么?

虚拟机分配给各个进程的运行内存是有限制的,LMK也会优先回收对 系统资源的占用多的进程。使用getprop dalvik.vm.heapsize可以查看设备给一个进程分配的内存大小:

exciter@exciterdeMacBook-Pro seal_troy_ucan_android_diandiankan % adb shell
zeus:/ $ getprop dalvik.vm.heapsize
512m
zeus:/ $ 

多进程的作用和优势主要有以下几点:

  • 突破进程内存限制,如图库占用内存过多;
  • 功能稳定性:独立的通信进程保持长连接的稳定性;
  • 规避系统内存泄漏: 独立的WebView进程阻隔内存泄露导致的问题;
  • 隔离风险:对于不稳定的功能放入独立进程,避免导致主进程崩溃。

2 Binder与传统的IPC机制对比

Binder共享内存Socket
性能需要拷贝一次无需拷贝需要拷贝两次
特点基于C/S架构,易用性高控制复杂,易用性差基于C/S 架构 作为一款通用接口,其传输 效率低,开销大
安全性为每个APP分配UID,同时支持实名和匿名依赖上层协议,访问接入点是开放的,不安全依赖上层协议,访问接入点是开放的,不安全

3 传统IPC机制(比如Socket)的原理

IPC机制的核心都是通过内存去传输数据,学习IPC机制就需要首先了解下内存划分相关知识。

内存被操作系统划分成两块:用户空间和内核空间,用户空间是用户程序代码运行的地方,内核空间是内核代码运行的地方。为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响。每个进程会单独分配一块用户空间,所有进程共用一块内核空间。

在传统的IPC机制中,比如Socket,进程间通信传输数据需要进行两次copy。每个进程会划分为两部分,分别是用户空间和内核空间,他们之间通过system_call,也就是系统调用去进行文件的操作。

进程中的用户空间和内核空间都属于虚拟内存,他们分别指向物理内存中的某一块,这里的物理内存指的就是设备中的内存条。

每个用户空间的虚拟内存指向不同的物理内存,而每个进程中的内核空间的虚拟内存会开辟一个虚拟内存块,这些虚拟内存块指向的是同一块物理内存。

处于用户空间的状态叫做用户态,处于内核空间的状态叫做内核态。

当进程间通信的时候,需要将进程1中的Data(下图中的白色圆形代表)复制到进程2中,这个时候数据在用户空间1指向的物理内存1中,然后通过system_call调用linux内核提供的copy_from_user接口,将数据复制到内核空间指向的物理内存中,然后进程2通过system_call调用linux内核提供的copy_to_user接口,再将数据复制到用户空间2指向的物理内存2中。这样就实现了进程间的通信。

4 Binder的原理,如何跨进程的?如何实现一次Copy?

而在Binder中,整体通信机制和传统IPC一样,那么为何能实现一次copy,这是因为在物理内存的指向上做了改动。

在Binder中,内核空间和进程2中分别另外开辟了一块虚拟内存,这两块虚拟内存指向物理内存中的同一块内存空间。然后传递数据的时候,将数据从进程1的物理内存1中复制到内核空间和进程2共同指向的物理内存块中,也就是下图物理内存中的紫色部分。这样进程2中就获取到了数据。这样就实现了一次copy。

5 MMAP原理

Linux通过将一个虚拟内存区域与一个磁盘上的对象关联起来,以初始化这个虚拟内存区域的内容,这个过程称为内存映射(memory mapping)。

对文件进行mmap,会在进程的虚拟内存分配地址空间,创建映射关系。实现这样的映射关系后,就可以采用指针的方式读写操作这一段内存,而系统会自动回写到对应的文件磁盘上。

所有的系统资源管理都是在内核空间中完成的。比如读写磁盘文件,分配回收内存,从网络接口读写数据等等。 用户空间通过系统调用让内核空间完成这些功能。

写文件流程:

1、调用write,告诉内核需要写入数据的开始地址与长度 。

2、内核将数据拷贝到内核缓存 。

3、由操作系统调用,将数据拷贝到磁盘,完成写入。

关注木水小站 (zhangmushui.cn)和微信公众号【木水Code】,及时获取更多最新技术干货。