from《计算机操作系统》第四版
逢考必过!加油!!!
4.1 存储器的层次结构
存储器的管理主要是指内存上面的管理和分配
几乎每一条指令都涉及存储器的访问
4.1.1 多层结构的存储器系统
1. 存储器的多层结构
层次越高越接近CPU,存储介质的访问速度越快,价格越高,相对所配置的存储容量越小
- 操作系统存储管理管辖范畴(掉电后信息不存在)——可执行存储器,可用load或store进行访问
- CPU寄存器
-
- 寄存器
-
- 主存
-
- 高速缓存
-
- 主存储器
-
- 磁盘缓存
-
- CPU寄存器
- 设备管理管辖范畴(存储信息长期保存)——需要通过I/O设备实现,耗时高
- 辅存
-
- 固定磁盘
-
- 可移动存储介质
-
- 辅存
2. 可执行存储器
包括CPU寄存器、主存储器。
操作系统的存储管理负责对可执行存储器的分配、回收以及提供在存储层次间数据移动的管理机制
4.1.2 主存储器与寄存器
-
主存储器(主存或内存)
- 保存进程运行时的程序和数据
- 处理机从主存储器中取得指令和数据,并将器所取得的指令放入指令寄存器中,而将其所读取的数据装入到数据寄存器中;反之,将寄存器中的数据存入到主存储器中。
-
寄存器
寄存器与处理机速度相同。为了缓和主存储器访问速度远低于CPU执行指令的速度的矛盾,在OS引入寄存器和高速缓存。
4.1.3 高速缓存和磁盘缓存
1. 高速缓存
备份主存中较常用的数据,减少处理机对主存的访问。
一级缓存速度最高,容量最小。
2. 磁盘缓存
缓和磁盘I/O速度远低于对主存的访问速度,为缓和二者之间速度上的不匹配,设置了磁盘缓存。
暂时存放频繁使用的一部分磁盘数据和信息。
本身不是实际存在的存储器,而是利用主存中部分存储空间暂时存放从磁盘中读出或写入的信息。
4.2 程序的装入和链接
编译(形成obj模块) ⇒ 链接(装入模块是可执行,但在磁盘中,因此需要进行下一步) ⇒ 装入(由装入模块装入内存中才可执行,之后由调度程序进行调度)
4.2.1 程序的装入
作业空间(逻辑空间,作业所有指令所占的空间)不等于物理空间
作业空间中指令的执行是按地址来执行,实际上访问指令是访问地址,此时地址即逻辑地址,地址是一个相对概念,可人为定(但约定都以0开始),即相对地址(都是相对第一条指令的位置——位移量d)
内存空间(物理空间,实在的存储器)
内存空间的存储单元的编号为物理地址,CPU实际访问物理地址,也是相对概念(相对第一条指令的位置)
物理地址与逻辑地址不同,因为逻辑地址都是从0开始,而物理地址不一定从0开始,相同的偏移量物理地址不同,是根据当前物理地址的开始位置计算偏移得到。
若物理地址的第一个指令与逻辑地址的第一个指令地址相同,则其余的相对位置一致,即两个地址一样。
如逻辑空间中,逻辑地址2的指令为LOAD1,98(将逻辑地址中98的数据装载到存储器1中),而此时逻辑地址2对应的物理地址假设为物理地址100,而此时如果继续访问物理地址98,则无法获得正确的数据,因为此时逻辑地址98对应的物理地址应该为196,指令应该是从物理地址196中的数据装入存储器1。
1. 绝对装入方式
程序中所使用的绝对地址,既可在编译或汇编时给出,也可以由程序员直接赋予。如物理地址开始为100,则逻辑地址也应该从100开始,此时两地址对应关系相同。但多个程序时,无法事先知道物理地址,因此通常宁可采用符号地址,然后在编译或汇编时,再将这些符号地址转换为绝对地址
2. 可重定位装入方式
装入时修改指令中的逻辑地址变为实际物理地址(物理上的地址初始位置+逻辑地址),平移变换,从0开始变换到从n开始(n为物理地址的第一个指令地址)
把装入是对目标程序中指令和数据地址的修改过程称为重定位。
3. 动态运行时装入方式
实际存入内存后,地址可能会发生变化,此时地址已经转换成物理地址,无法再次转换,因此有动态运行时装入。
将逻辑地址转换为绝对地址的操作推迟到程序真正要执行时才进行。装入内存后的地址都是相对地址。
必须要有一个地址变换机构。
装入实际上是重定位过程(逻辑地址到物理地址的变换),只是重定位实际不同。绝对装入方式在装入之前重定位,可重定位装入方式在装入过程中重定位,动态运行时装入方式在装入之后重定位。
4.2.2 程序的链接
链接:将多个模块连接成一个模块的重定位过程(将相对地址进行修改;变换外部调用符号)
1. 静态链接方式
在程序运行之前,先将各目标模块以及它们所需的库函数链接成一个完整的装配模块,以后不再拆开。
2. 装入时动态链接
在装入内存是,采用边装入边链接的链接方式。
- 便于修改和更新
- 便于实现对目标模块的共享
但运行比静态链接时间更长
3. 运行时动态链接
将对某些模块的链接推迟到执行时才执行。在执行过程中,当发现一个被调用模块尚未装入内存时,立即由OS去找到该模块并将之装入内存,把它链接到调用者模块上。
加快程序的装入过程,节省大量的内存空间
4.3 连续分配方式管理方式
4.3.1 单一连续分配
最简单的存储管理,只能用于单用户、单任务的操作系统
把内存分为系统区和用户区:
- 系统区:仅提供给OS使用,通常放在内存的低址部分
- 用户区:除系统区以外的全部内存空间,提供给用户使用
4.3.2 固定分区分配
1. 划分分区的方法
- 分区大小相等
- 分区大小不等
2. 内存分配
- 分区说明表
【分区号,大小,起址(基址),状态】
- 存储空间分配情况
便于管理,但是不够灵活,因为有可能是160KB的分区在话给你了20KB的数据
4.3.3 动态分区分配
根据进程的实际需要,动态地为之分配内存空间。
1. 分区分配中的数据结构
- 空闲分区表
- 空闲分区链(更容易表示动态结构)
占用分区时删除节点,回收空间则插入到相应的空间
2. 动态分区分配算法
无好坏之分
-
首次适应算法
每次冲头开始找
-
循环首次适应算法
-
最佳适应算法
-
最坏适应算法
-
快速适应算法
-
伙伴系统
-
哈希算法
3. 分区分配操作
-
- 分配内存(链表修改)
事先规定不可再分割的剩余分区的大小
-
- 回收内存(链表修改)
- F1+回收区:与上分区合并
- 回收区+F2:与下分区合并
- F1+回收区+F2:三个分区合并
- 回收区不与F1或F2相邻:单独建立一个新表项
4.3.4 基于顺序收缩的动态分区分配算法【P140】
- 首次适应算法FF
分配内存时,从链首开始顺序查找,知道找到一个大小能满足要求的分区为止 - 循环首次适应算法NF
从上次找到的空闲分区的下一分区开始查找 - 最佳适应算法BF
每次分配总把能满足要求、又是最小的空闲分区分配给作业 - 最坏适应算法WF
每次分配总把能满足要求、又是最大的空闲分区分割一部分给作业
4.3.5 基于索引搜索的动态分区分配算法【P141】
- 快速适应算法
即分类搜索法,将空闲分区根据容量大小进行分类,对每一类具有相同容量的所有空闲分区,单独设立一个空闲分区链表,系统中存在多个空闲分区链表。 - 伙伴系统
规定无论已分配分区或空闲分区,其大小均为2的k次幂。根据空闲分区按分区大小分类。 - 哈希算法
利用哈希快速查找,以及空闲分区在可利用空闲分区表中的分布规律建立哈希函数,构造一张以空闲分区大小为关键字的哈希表,哈希表的每一个表象记录了一个对应的空闲分区链表表头指针。
4.3.6 动态可重定位分区分配
1. 紧凑(内存整理)
必须使用动态重定位
代价高,移位时程序停止
2. 动态重定位
动态运行时转入的方式中,作业装入内存后的所有地址仍然是逻辑地址,而将相对地址转换为物理地址的工作被推迟到程序指令真正执行。为使地址的转换不会影响到指令的执行速度,必须由硬件地址变换机构的支持,即须在系统中增设一个重定位寄存器,用来存放程序(数据)在内存中的起始地址。程序在执行时,真正访问的内存地址是相对地址与重定位寄存器中的地址相加而形成。
重定位寄存器,不需装入程序来实现重定位。由此才能重定位。
3. 动态重定位分区分配算法
4.4 对换(交换)
4.4.1 多道程序环境下的对换技术
1. 对换的引入
对换:把内存中暂时不能运行的进程或暂时不要的程序和数据调到外存上,以便腾出足够的内存空间,再把已具备运行条件的进程或进程所需要的程序和数据调入内存。
提高内存利用率
2. 对换的类型
-
整体对换
中级调度 (Intermediate Scheduling)= 内存调度
当挂起状态的进程已具备运行条件且内存又有空闲时,由中级调度来决定,把外存上的那些已具备运行条件的就绪进程再重新调入内存,并修改其为就绪状态,挂在就绪队列上等待。实际上存储器管理的对换功能。以整个进程为单位,称为“进程对换”或“整体对换”
-
分页(分段)对换
对换是以一个“页面”或“分段”为单位进行的,则称为页面对换或分段对换。
必须实现对对换空间的管理、进程的传出和进程的换入
4.4.2 对换空间的管理
对具有对换功能的OS中,通常把磁盘分为文件区和对换区
1. 对换空间管理的主要目标
- 对文件区管理的主要目标
文件大多较长时间驻留在外存,主要目标是提高文件存储空间利用率,其次才是提高访问速度。采用离散分配方式。
- 对对换空间管理的主要目标
对换空间用于存放从内存换出的进程。驻留时间短暂,对操作的频率高。主要目标是提高进程换入和换出的速度,其次才是提高空间利用率。采用连续分配方式。
2. 对换区空闲盘块管理中的数据结构
其形式与内存在动态分区分配方式中所用数据结构相似,即同样可以用空闲分区表或空闲分区链。在空闲分区表中的每个表目中应包含两项, 即对换区的首址及其大小,它们的单位是盘块号和盘块数。
3. 对换空间的分配与回收
与动态分区方式时内存的分配与回收方法雷同。
4.4.3 进程的换出与换入
1. 进程的换出
每当一进程由于创建子进程而需要更多的内存空间,但又无足够的内存空间等情况发生时,系统应将某进程换出。
- 选择被换出的进程(处于阻塞状态且优先级最低)
- 进程换出过程
先申请对换空间,若申请成功,则启动盘块,将该进程的**程序和数据(非共享)**传送到磁盘的对换区上。若传送过程未出现错误,便可回收该进程所占用的内存空间,并对该进程的进程控制块做相应的修改。
2. 进程的换入
系统应定时地查看所有进程的状态,从中找出“就绪”状态但已换出的进程,将其中换出时间(换出到磁盘上)最久的进程作为换入进程,将之换入,直至已无可换入的进程或无可换出的进程为止。
4.5 基本分页存储管理方式(必考:分页)
离散分配的方式:
- 分页存储管理方式:将用户程序的地址空间分为若干个固定大小的区域,称为“页”。相应地,也将内存空间分为若干个物理块或页框,页和块的大小相同。可将用户程序的任一页放入任一物理块中,实现离散分配
- 分段存储管理方式:将用户程序的地址空间分为若干个大小不同的段,每段可定义一组相对完整的信息。存储器分配时以段为单位,这些段再内存中可以不相邻接,实现了离散分配
- 段页式存储管理方式:分页与分段两种存储方式相结合的产物。
4.5.1 分页存储管理的基本方法
1. 页面和物理块
- 页面
分页存储管理:是将一个进程的逻辑地址空间分成若干个大小相等的片,称为页面或页,并为各页加以编号,以0开始。相应地,也把内存的物理空间分成若干块,同样编号,如0#块、1#块。在为进程分配内存时,以块为单位将进程中的若干个页分别装入到多个可以不相邻接的物理块中。由于进程的最后一页经常装不满一块而形成了不可利用的碎片,称之为“页内碎片”
- 页面大小
在分页系统中的页面其大小应适中。页面若太小,一方面虽然可使内存碎片减小,从而减少了内存碎片的总空间, 有利于提高内存利用率,但另一方面也会使每个进程占用较多的页面,从而导致进程的页表过长,占用大量内存; 此外,还会降低页面换进换出的效率。然而,如果选择的页面较大,虽然可以减少页表的长度,提高页面换进换出的速度,但却又会使页内碎片增大。因此,页面的大小应选择得适中,且页面大小应是2的幂,通常为1KB~8 KB。
2. 地址结构
地址=【页号P、位移量W(即页内地址)】
0-11位为页内地址,即每页大小为4KB(212=4096个地址,每个地址存储一个字节Byte,即4096*1byte=4KB);同理12-31位,地址空间最多允许有1M页(220*1byte=1M)
1KB = 1024byte;2KB = 2^11byte;4KB = 2^12byte;1MB = 1024KB = 220byte;1GB=230byte
INT:整除函数,MOD:取余函数。
如系统页面大小为1KB,设A=2170B,则由上式可求得P=INT[2170/1024]=2, d=[2170] MOD 1024 = 122
位移量可称为页内地址
00000000
00000001
00000010
00000011
00000100
00000101
…
看最后两位是00、01、10、11循环,则位移量即0-3,前面的部分是页号
3. 页表(页面映射表)
页表实现从页号到物理块号的地址映射
记录每页的地址,但分页后的页号和块号有对应关系,也可以得出物理地址,所以不记录地址,而是直接记录块号。
【页号、块号】
块开头地址=页号*块号
将页号换成块号,即可变成内存地址(由分页结构所决定)
4.5.2 地址变换机构
基本任务:从逻辑地址到物理地址的转换。由于页内地址和物理地址一一对应,因此实际上只是将逻辑地址的页号转换为内存中的物理块号,借助页表完成。
1. 基本的地址变换机构
页表功能是由一组专门的寄存器来实现的,一个页表项用一个寄存器。但由于页表大,不可能都用寄存器来实现,因此页表大多驻留在内存中,在系统中只设置一个页表寄存器PTR,存放页表在内存的起始地址和页表的长度。进程未执行时,页表的始址和页表长度都放在本进程的PCB中。
页表寄存器【页表始址,页表长度】
先检查逻辑地址的页号是否越界,超过页面的地址,内存保护措施
要两次访问内存,时间慢,第一次查内存中的页表找到指定页的物理块号,再将块号与页内偏移量W拼接,形成物理地址;第二次访问,是从第一次所得地址中获得所需数据(或写入数据)。
2. 具有快表TLB的地址变换机构
为了提高地址变换速度,在地址变换机构中增设一个具有并行查询能力的特殊高速缓冲寄存器,又称为“联想寄存器”或“快表”,用以存放当前访问的那些页表项。
快表是在CPU寄存器
查页表和快表,若快表查到,直接访问物理地址,若找不到,则在页表找,并把信息记录在快表中
4.5.3 访问内存的有效时间
有效实际是从进程发出指定逻辑地址的访问请求,经过地址变换,到在内存中找到对应的实际物理地址单元并去除数据所需花费的总时间。
4.5.4 两级和多级页表
把页表当作一个作业,再进行离散分配。
为离散分配的页表再建立一张页表,称位外层页表。
1. 两级页表
【外层页号、外层页内地址、页内地址】
2. 多级页表
对于32位的机器,采用两级页表结构是合适的;但对于64位的机器,如果页面大小仍采用4 KB即212 B,那么还剩下52位, 假定仍按物理块的大小(212位)来划分页表,则将余下的42位用于外层页号。此时在外层页表中可能有4096 G个页表项, 要占用16384 GB的连续内存空间。 必须采用多级页表,将外层页表再进行分页,也是将各分页离散地装入到不相邻接的物理块中,再利用第2级的外层页表来映射它们之间的关系。
对于64位的计算机,如果要求它能支持2^64(=1844744 TB)规模的物理存储空间,则即使是采用三级页表结构也是难以办到的;而在当前的实际应用中也无此必要。因此把可直接寻址的存储空间减少为45位长度,用三级页表结构实现分页存储管理。
4.5.5 反置页表
按块号查页号
【块号、页号、进程标识符】
页号会重复,用进程标识符区别
4.6 基本分段存储管理方式
4.6.1 分段存储管理方式的引入
从用户和程序员的角度可以方便编程,分页是从系统角度提高内存利用率,但是修改了不知道是那个模块修改的
- 方便编程
- 信息共享
- 信息保护
- 动态增长
- 动态链接
4.6.2 分段系统的基本原理
1. 分段
【段号、段内地址(偏移量)】
每个段都是独立的逻辑空间,段内地址会重复,因此需要段号唯一确定地址。段号是人为分配或者编译系统分配的,段号和段内地址无关,因此无法求得段号
段的大小不一
2. 段表
分段式存储管理系统中,为每个分段分配一个连续的分区。进程中的各个段,可以离散地装入内存中不同的分区中。需要为每个进程建立一张段映射表,即段表。段表的作用是实现从逻辑段到物理内存的映射。
【段号、段长、基址(段在内存中的起始地址)】
记录作业的每个段
3. 地址变换机构
物理地址 = 段表的基址+有效地址的偏移量
4. 分页和分段的主要区别
- 页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头, 提高内存的利用率。或者说, 分页仅仅是由于系统管理的需要而不是用户的需要。段则是信息的逻辑单位,它含有一组其意义相对完整的信息。 分段的目的是为了能更好地满足用户的需要。
- 页的大小固定且由系统决定,由系统把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而在系统中只能有一种大小的页面;而段的长度却不固定, 决定于用户所编写的程序,通常由编译程序在对源程序进行编译时,根据信息的性质来划分。
- 分页的作业地址空间是一维的,即单一的线性地址空间,程序员只需利用一个记忆符,即可表示一个地址; 而分段的作业地址空间则是二维的,程序员在标识一个地址时,既需给出段名, 又需给出段内地址。
4.6.3 信息共享
1. 分页系统中对程序和数据的共享
2. 分段系统中程序和数据的共享
可重入代码称为“纯代码”,是一种允许多个进程同时访问的代码。可重入代码不允许任何进程对它进行修改。因此每个进程都必须配以局部数据区,把执行中可能改变的部分拷贝到数据区。
4.6.4 段页式存储管理方式
1. 基本原理
先将用户查询分成若干个段,再把每个段分成若干个页,并为每一个段赋予一个段名。
段表【页表始址 | 页表长度】