持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
3.内存管理
内存管理:
引入目的:更好的支持多道程序并发执行,提升系统性能
程序的编译:由编译程序将用户源代码编译成若干个目标模块;
程序的链接:由链接程序将编译后形成的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块;
- 静态链接:在程序运行之前链接
- 装入时动态链接:在装入内存时,采用边装入边链接的链接方式
- 运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接
程序的装入:由装入程序将装入模块装入内存运行;
- 绝对装入:适合单道程序环境
- 静态重定位:适合装入之后不再移动的情况
- 动态重定位:适合装入之后还会移动的情况
地址空间:
- 逻辑地址空间:是指一个源程序在编译或者链接装配后指令和数据所用的所有相对地址的空间;
- 物理地址空间:内存中物理单元的集合;
地址重定位:通过地址转换将逻辑地址转换为物理地址。
内存保护:
- 上、下限寄存器:分别与上、下限寄存器比较
- 基址、限长寄存器:与限长寄存器比较,与基址寄存器相加
管理方式:
-
连续分配:产生内部碎片;用户进程(或作业)在主存中都是连续存放的
-
单一连续分配:分配到内存固定区域,只适合单任务系统;
-
固定分区分配:分配到内存中不同的固定区域,分区可以相等也可以不等;
- 产生内部碎片
-
动态分区分配:
-
产生外部碎片
-
基本概念:按照程序的需要进行动态的划分
-
分配算法:
- 首次适应:空闲区按地址从小到大为序,分配第一个符合条件的分区;
- 最佳适应:空闲区按空间大小从小到大排序,分配第一个符合条件的分区;
- 最坏适应:空闲区按空间从大到小排序,分配第一个符合条件的分区;
- 邻近适应:空闲区按地址地址递增的次序排列,分配内存时从上次查找结束的位置开始继续查找;
-
-
-
非连续分配:允许一个程序分散地装入到不相邻的内存分区中,需要额外的空间去存储分散区域的索引
-
基本分页:内存分为固定的块,按物理结构划分,会有内部碎片;
- 主存、进程都划分为大小固定的块,进程在执行时,以块为单位申请主存中的块空间;
- 进程中的块为页,内存中的块为页框。系统为每个进程建立一张页表,页表记录页面在内存中对应的物理块号,实现从页号到物理块号的地址映射;
- 页式管理中地址空间是一维的;
-
基本分段:内存块的大小不固定,按逻辑结构划分,会有外部碎片;
- 段式管理方式按照用户进程中的自然段划分逻辑空间。段内要求连续,段间不要求连续。段号和段内偏移量必须由用户显示提供。
- 方便编程、共享、保护、动态链接和增长。
-
段页式:基本分段和基本分页的结合,会有内部碎片;
- 作业的逻辑地址分为:段号、页号和页内偏移量;采用分段方法来分配和管理用户地址空间,采用分页方法来管理物理存储空间;开销大。
-
请求分页存储管理:采用虚拟技术,开始运行时不必将作业全部一次性装入内存;
-
多级页表:将页表的10页空间也进行地址映射,建立上一级页表,用于存储页表的映射关系;
-
多道程序下的内存扩充:
-
覆盖:预先设定覆盖段,覆盖掉暂时不用的内容,通常在同一个程序之中进行;
-
交换:把处于等待的程序暂时移到外存,通常在不同程序之间进行;
-
虚拟内存:只能基于非连续分配技术。
-
引入原因:在逻辑上扩充内存
-
时间局部性:程序中存在着大量的循环操作;
-
空间局部性:程序在一段时间内所访问的地址,可能集中在一定的范围内;
-
组成部分:
- 页表机制:通过查表获取相关信息;
- 中断机制:要访问页不在内存时产生缺页中断
- 地址变换机构:把逻辑地址变换成物理地址
- 内存和外存:需要一定容量的内存和外存支持
-
置换算法:
- 最佳置换算法(OPT):选择以后不用的页面
- 先进先出(FIFO):选择最先装入的页面
- 最近最久未使用(LRU):选择最近最近未使用的页面
- 时钟置换算法(最近未用算法):选择最近未用的页面
- 改进型CLOCK:考虑页面修改问题
-
地址翻译:TLB->页表(TLB不命中)->Cache->主存->外存
-
页面分配策略:
- 固定分配局置换:每个进程分配一定数目的物理块,在整个运行期间不变,缺页时只在该进程在内存中的页面中进行置换;
- 可变分配全局置换:为每个进程分配一定数目的物理块,操作系统自身也保持一个空闲物理块队列;
- 可变分配局部置换:若进程在运行中频繁地缺页,系统再为该进程分配若干物理块;
抖动(颠簸):
- 刚换出的页面马上又要换入内存;刚换入的页面马上就要换出内存;
工作集(驻留级):
- 指在某段时间间隔内,进程要访问的页面集合。
虚拟内存空间大小:
- <=内存容量和外存容量之和
- <=计算机的地址位数能容纳的最大容量
虚拟存储的页表项:
- 页号
- 物理块号
- 状态位P:用于指示该页是否已调入内存,供程序访问参考;
- 访问字段A:用于记录本页在一段时间内被访问的次数,或记录本页最近已有多长时间未被访问,供置换算法换出页面时参考;
- 修改位M:标识该页在调入内存后是否被修改过;
- 外存地址
Belady现象:进程的缺页次数随着分配给进程的页框个数的增加而增加,只有FIFO队列式页面置换算法才有。\
页式地址变换.png
快表(联想寄存器TLB):用来存放当前访问的若干页表项,以加速地址变换的过程,若所需访问页号在快表中则可减少一次内存访问。
作者:PC_Repair
链接:www.jianshu.com/p/35eccacdc…
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
进程同步:
引入原因:协调进程之间的相互制约关系
制约关系:
- 同步:需要在某些位置上协调进程之间的工作次序而等待、传递信息所产生的制约关系
- 互斥:当一个进程进入临界区使用临界资源时,其他要求进入临界区的进程必须等待
临界资源:多个进程可以共享系统中的资源,一次仅允许一个进程使用的资源叫临界资源;
临界区互斥:访问临界资源的那段代码称为临界区
-
原则:空闲让进、忙则等待、有限等待、让权等待
-
基本方法:
-
软件实现:
- 单标志法:违背”空闲让进“原则
- 双标志法先检查:违背”忙则等待“原则
- 双标志法后检查:会导致”饥饿“现象
- 皮特森算法:单标志法和双标志法后检查的结合
-
硬件实现:
- 中断屏蔽法:进区关中断,出区开中断
- 硬件指令法:设立原子操作指令
-
信号量:利用PV操作实现互斥
- P操作即wait(S)
- V操作即signal(S)
-
管程:
-
定义:由一组数据以及定义在这组数据上的对这组数据的操作组成的软件模块
-
组成:
- 局部于管程的共享结构数据(变量)说明
- 对该数据结构进行操作的一组过程
- 对局部于管程的共享数据设置初始值的语句,此外还需要为管程赋予一个名字
-
引入管程的目的:解决临界区分散所带来的管理和控制问题。在没有管程之前,对临界区的访问分散在各个进程之中,不易发现和纠正分散在用户程序中的不正地使用P、V操作等问题。管程将这些分散在各进程中的临界区集中起来,并加以控制和管理,管程一次只允许一个进程进入管程,从而便于系统管理共享资源,又能保证互斥。
死锁:
产生原因:非剥夺资源的竞争和进程的不恰当推进顺序
定义:多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进
解决方案:
-
预防死锁:
- 破坏互斥条件:
- 破坏不可剥夺条件:
- 破坏请求和保持条件:
- 破坏循环等待条件:
-
避免死锁:
- 安全状态:能找到一个分配资源的序列能让所有进程都顺利完成
- 银行家算法:采用预分配策略检查分配完成时系统是否处于安全状态
-
检测死锁:利用死锁定理化简资源分配图以检测死锁的存在
-
资源分配图:
-
圆圈代表进程;
-
框中的一个点代表一类资源中的一个资源;
-
进程到资源的有向边叫请求边;
-
资源到进程的边叫分配边;
\
资源分配图.png
-
-
-
解除死锁:
- 资源剥夺法:挂起某些死锁进程并抢夺它的资源,以便让其他进程继续推进
- 撤销进程法:强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源
- 进程回退法:让进程回退到足以回避死锁的地步
算法:
- 银行家算法为死锁避免算法;
- 死锁检查算法和资源分配图化简法为死锁检测;
- 资源有序分配算法为死锁预防策略;
所谓CPU繁忙型的作业,是指该类作业需要大量的CPU时间进行计算,而很少请求I/O操作。I/O繁忙型的作业是指CPU处理时,需频繁的请求I/O操作。
周转时间 = 作业完成时间 - 作业提交时间;
平均周转时间 = (作业1的周转时间 + ... + 作业n的周转时间)/ n ;
带权周转时间 = 作业周转时间 / 作业实际运行时间;
平均带权周转时间 = (作业1的带权周转时间 + ... + 作业n的带权周转时间)/ n;
响应比Rp = (等待时间 + 要求服务时间) /要求服务时间;