学习笔记1-深入理解Android内核设计思想

4.1 计算机体系结构(Computer Architecture)

4.1.1 冯·诺依曼结构

两个深远影响的观点:

  • 采用二进制,抛弃十进制

  • 程序存储(stored-program)

冯·诺依曼结构.png

4.1.2 哈佛结构

对冯诺依曼结构的改进与完善,区别在指令与数据并不保存在同一个存储器。

这意味着:

  • 指令与数据可以有不同的的数据宽度;

  • 执行速度更快。

哈佛结构.png

计算机结构的基本元素:

  • 中央处理器(CPU)

  • 内存储器

  • I/O设备

4.2 什么是操作系统

定义:

计算机操作系统是负责管理系统硬件,并为上层应用提供稳定编程接口和人机交互界面的软件集合。

最核心的工作:硬件管理与抽象。

肩负两大重任:

  • 面向下层:管理硬件(CPU、内存、Flash、各种IO设备)

  • 面向上层:一方面,为用户提供可用的人机交互界面;另一方面,负责为第三方程序的研发提供便捷、可靠、高效的API。

操作系统的难点:进程和内存管理、硬件驱动的支持等,这正是Linux的长处所在。

4.3 进程间通信的经典实现

进程间的通信(Inter-process communication,IPC)是指运行在不同进程(不论是否在同一台机器)中的若干线程间的数据交换。

实现方式:消息传递、管道、文件共享、操作系统提供的公共信息机制等等。

4.3.1 共享内存(Shared Memory)

一种常用的IPC机制,优势:共享内存区域,减少数据的复制操作,速度快。

实现步骤:

  • 创建内存共享区

  • 映射内存共享区

  • 访问内存共享区

  • 进程间通信

  • 撤销内存映射区

  • 删除内存共享区

4.3.2 管道(Pipe)

一种常见的IPC方式

  • 分立管道的两边,进行数据的传输通信

  • 管道是单向的

  • 一根管道同时具有“读取”端(read end)和“写入”端(write end)

  • 管道有容量限制

4.3.3 UNIX Domain Socket(UDS)

专门针对单机内的进程间通信,有时称为IPC Socket。

Network Socket是以TCP/IP协议栈为基础,UDS因为是本地内的“安全可靠操作”,实现机制上并不依赖于这些协议。

典型流程:

UNIX Domain Socket的通信流程.png

UDS的基本流程与传统Socket一致,只是在参数上有区分:

  • 服务器端监听IPC请求;

  • 客户端发起IPC申请;

  • 双方成功建立起IPC连接;

  • 客户端向服务端发送数据,证明IPC通信是有效的

4.3.4 Remote Procedure Calls(RPC)

涉及的通信双方通常运行于两台不同的机器中。

RPC通信图释.png

4.4 同步机制的经典实现

同步:如果多个进程间存在时序关系,需要协同工作以完成一项任务

互斥:如果多个进程并不满足协同的条件,而只是因为共享具有排他性的资源时所产生的关系。

4.4.1 信号量(Semaphore)

涉及的元素:信号量(S)、PV原语操作(有时称wait()、signal())。

S:共享资源的可用数量

P: 减少S的计数(进入共享区的操作)

V:增加S的计数(退出共享区的操作)

PV操作图.png

4.4.2 Mutex

是Mutual Exclusion的缩写,即互斥体

4.4.3 管程(Monitor)

一种控制更为简单的同步手段。

可以被多个进程/线程安全访问的对象(object)或模块(module)。

具备安全性、互斥性、共享性。

4.4.4 Linux Futex

核心优势是Fast。

4.4.5 同步范例

生产者与消费者问题:

两个进程共享一块大小为N的缓冲区,其中一个进程负责填充数据(生产者),另一个进程负责读取数据(消费者)。

问题的核心有两点:

  • 当缓冲区满时,禁止生产者继续添加数据,直到消费者读取了部分数据;

  • 当缓冲区空时,消费者应等待对方继续生产后再执行操作。

解决方式:信用量,用到3个Semaphore,功能如下:

  • S_emptyCount: 用于生产者获取可用的的缓冲空间大小,初始N

  • S_fillCount: 用于消费者获取可用的数据大小,初始为0

  • S_mutex: 用于操作缓冲区,初始为1

生产者的执行步骤:

  • 循环开始;

  • Produce_item;

  • P(S_emptyCount)

  • P(S_mutex)

  • Put_item_to_buffer

  • V(S_mutex)

  • V(S_fillCount)

  • 继续循环

消费者的执行步骤:

  • 循环开始

  • P(S_fillCount)

  • P(S_mutex)

  • Read_item_from_buffer

  • V(S_mutex)

  • V(S_emptyCount)

  • Consume

  • 继续循环

4.5 Android中的同步机制

4.5.1 进程间同步 - Mutex

头文件:frameworks/native/include/utils/Mutex.h

既可以处理进程内同步、又可以解决进程间同步。

4.5.2 条件判断 - Condition

头文件:frameworks/native/include/utils/Condition.h

核心思想:判断“条件是否已经满足”,如果满足则马上返回,继续执行未完成的动作,否则就进行休眠等待,直到条件满足时有人唤醒它。

4.5.3 “栅栏、障碍” - Barrier

头文件:frameworks/native/services/surfaceflinger/Barrier.h

Barrier是填充了“具体条件”的Condition,专门为SurfaceFlinger而设计。

通常被用于对某线程是否初始化完成进行判断,这种场景具有不可逆性。

4.5.4 加解锁的自动化操作 - Autolock

在Mutex类内部的嵌套类Autolock,实现加、解锁的自动化操作。

当Auto构造时,会主动调用内部成员变量mLock的lock()方法获取一个锁。

而析构时正好相反,调用它的unlock()方法释放锁。

4.5.5 读写锁 - ReaderWriterMutex

基础仍是mutex,特点是 允许有多个对象共享Read锁,但同时却只能有唯一一个对象拥有Write锁。

4.6 操作系统内存管理基础

内存管理是操作系统的重点和难点

内存管理重点理解几个核心:虚拟内存、内存分配与回收、内存保存。

4.6.1 虚拟内存(Virtual Memory)

虚拟内存:为大体积程序的运行提供了可能。

基本思想:

  • 将外存储器的部分空间作为内存的扩展

  • 当内存资源不足时,系统将按照一定算法自动挑选优先级低的数据块,并把它们存储到硬盘中。

  • 后续如果需要用到硬盘中的这些数据块,系统将产生“缺页”指令,然后把它们交换回内存中。

  • 这些操作是由操作系统内部内核自动完成,对上层应用“完全透明”。

涉及3种不同的地址空间:

1、逻辑地址

是程序编译后所产生的地址,Segment Selector(段选择子, 16bit) + Offset (偏移值,32bit)

2、线性地址

是逻辑地址经过分段机制转换后形成的

3、物理地址

是指机器真实的物理内存所能表示的地址空间范围,64KB内存的物理地址范围是 0x0000 - 0xFFFF

地址空间的转换过程简图.png

4.6.2 内存保护(Memory Protection)

4.6.3 内存分配与回收

分Native层(C/C++)、Java层

4.6.4 进程间通信 - mmap

IPC方式: 通过映射同一块物理内存来共享内存,减少数据复制次数,提高效率。

mmap可以将某个设备或者文件映射到应用进程的内存空间中,这样访问这块内存就相当于对设备/文件进行读写,而不需要通过read()、write()。

4.6.5 写时拷贝技术(Copy on Write)

基本思想:多个对象在起始时共享某些资源(如代码段、数据段),直到某个对象需要修改该资源才拥有自己的一份拷贝。

4.7 Android中的Low Memory Killer

Linux底层内核的内存监控机制:OOMKiller,核心思想:按照优先级顺序,从低到高逐步杀掉进程,回收内存。

优先级的设定策略需综合以下几个因素:

  • 进程消耗的内存

  • 进程占用的CPU时间

  • oom_adj(OOM权重)

Android扩展出自己的内存监控体系,Linux的“内存杀手”要等到系统资源“濒临绝境”的情况下才产生效果,而Android则实现了“不同梯级”的Killer(Low Memory Killer(LMK))。

LMK的源码在内核工程的driver/staging/android/Lowmemorykiller.c中。

4.8 Android匿名共享内存(Anonymous Shared Memory)

Anonymous Shared Memory(简称Ashmem)是Android特有的内存共享机制,可以将制定的物理内存分别映射到各个进程自己的虚拟地址空间中,从而便捷地实现进程间的内存共享。

应用实例:基于ashmem设备来实现跨进程内存共享,如MemoryDealer。

匿名共享内存涉及设备驱动、Binder原理等一系列技术,比较难理解,等学习相关基础知识,再来攻克。

4.9 JNI

JNI(Java Native Interface)是一种允许运行于JVM的Java程序去调用(反向亦然)本地代码的编程框架。

有3种情况需要用到JNI:

  • 应用程序需要一些平台相关的feature的支持,而Java无法满足

  • 兼容以前的用其他语言书写的代码库

  • 应用程序的某些关键操作对运行速度要求较高。

JNI涉及以下两方面:

  • Java Code -> Native Code

  • Native Code -> Java Code

4.9.1 Java函数的本地实现

创建一个可供Java代码调用的本地函数步骤:

  • 将需要本地实现的Java方法加上native声明;

  • 使用javac命令编译Java类

  • 使用javah生成.h头文件

  • 在本地代码中实现native方法

  • 编译上述的本地方法,生成动态链接库

  • 在Java类中加载这一动态链接库

  • Java代码中其他地方可以正常调用这个native方法

4.9.2 本地代码访问JVM

上节内容的“逆向”操作,本地层(C/C++)访问JVM空间(Java)。

4.10 Java中的反射机制

4.11 学习Android系统的两条线索

主线:操作系统的体系结构、硬件组成

辅线:在主线的基础上,以Android系统的5层框架为辅,逐一解析各层框架中的重要元素,或拾级而上,或深入浅出,直到问题的最根源处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容