一、存储体系
1、存储器的层次结构:
- 高速缓存Cache
- 内存;
- 固态硬盘SSD
- 磁盘/外存
2、内存:
- 系统区:存放操作系统内核;
- 用户区:存放用户程序和数据;
3、内存管理
操作系统对内存的划分和动态分配就是内存管理。
主要工作:将程序载入内存以让CPU执行程序。
目的:将内存区域进行划分以容纳多个进程(多道程序设计);有效分配内存以容纳尽量多的进程。
二、存储管理的要求
1、重定位(逻辑地址转物理地址)
物理地址空间指内存中物理单元的集合,是地址转换的最终地址。进程在运行时执行指令和访问数据最后都要通过物理地址从主存中存取。当装入程序将可执行代码装入内存时,必须通过地址转换将逻辑地址转换成物理地址,这一过程就称为地址重定位。
1、逻辑地址/相对地址
逻辑地址:并不是程序在内存中的实际地址,而是程序在内存中的相对地址或者说相对于当前进程某一点(程序起始位置或段基地址)的偏移位置;(逻辑地址并不唯一)
2、物理地址/绝对地址
物理地址也称为绝对地址,是内存的实际地址——加载到内存地址寄存器(CS,IP)中的地址;
3、多道程序和共享内存技术要求程序使用相对地址以支持重定位
原因:
- 程序员不知道程序在运行时在内存中所处的位置(物理地址未知);
- 处于内存某一块区域的程序代码在运行中可能被换出到外存,后来又被换进内存的另一块区域
重定位一般要求一定的硬件(CPU)支持。
2、保护(内存审查)
多道程序和共享内存技术要求一个进程不能对其他进程进行有意或无意的非授权访问。
内存分配之前需要保护操作系统不受用户进程的影响,同时保护用户进程不受其他用户进程的影响。通过采用重定位寄存器和界地址寄存器来实现这种保护。重定位寄存器包含最小的物理地址值,界地址寄存器包含最大的物理地址值。程序在运行(因为程序在编译时无法明确物理地址)时首先将逻辑地址加上基址寄存器中的值产生一个绝对地址,然后将得到的结果与界限寄存器的值相比较,若这个地址在界限范围内则继续该指令的执行;否则操作系统发出一个中断信号,以某种方式对这个错误进行响应。
CPU执行调度程序时要进行保护。
每个进程映像根据基址和界限寄存器的内容被隔开,以免受到其他进程的越权访问。
程序的内存引用只能在运行时检查:
- 重定位导致无法在编译时检查绝对地址;
- 多数程序设计语言允许地址的动态计算;
- 通常整合在重定位的硬件机制中(软件上难以预计所有非法情况,开销太大)
3、共享
支持不同进程访问内容的同一区域。
4、逻辑组织
逻辑组织就是操作系统可执行的程序的结构。
从物理上看,主存和辅存通常是一维线性结构;
反映程序组织的逻辑性,采用某种模块化形式组织用户程序及数据:
- 模块化有利于设计期间的编程;
- 模块化有利于运行时刻的保护;
- 模块化有利于运行时刻的共享;
分段存储管理技术最符合用户组织程序的观点。
5、物理组织
程序在内存中的存放结构。物理组织是操作系统进行资源管理的一部分工作。
6、覆盖技术和交换技术
这两种技术是在多道程序环境下扩充内存的方法。覆盖技术主要用在早起的操作系统;交换技术被广泛用于小型分时系统,它的发展导致了虚存技术的出现。
共同点:
- 进程的程序和数据主要放在外存;
- 只有当前需要执行的部分才放在内存;
- 内外存之间进行信息交换;
1、覆盖技术(overlaying)
把程序划分为若干个功能上相对独立的程序段,按照其自身的逻辑结构让那些不会同时执行的程序段共享一块内存区域。
首先把用户空间分成一个固定区和若干个覆盖区,将经常需要执行的程序部分放在固定区,其他部分按调用关系分段。在程序运行时,将即将需要被访问的段放入覆盖区,其他段放在外存中,在需要调用前系统再将其调入覆盖区,替换覆盖区中原有的段。
覆盖技术打破了必须将一个进程的全部信息装入主存后才能运行的限制。
2、交换技术(swapping)
当内存空间紧张时系统将内存中某些进程暂时移到外存(swap out),把外存中某些进程换进内存(swap in),占据前者原来所占用的区域。交换技术其实是进程在内存与外存之间的动态调度。
交换要求每个进程的执行时间比交换时间长以有效地使用CPU。
3、两者的比较:
- 交换技术不要求用户给出程序段之间的逻辑覆盖结构;
- 交换发生在不同的进程或作业之间,而覆盖发生在同一进程或作业之内;
三、分区存储管理技术(partition)
内存连续分配管理方式:指的是为一个用户程序分配一个连续的内存空间。主要包括单一连续分配、固定分区分配和动态分区分配。
1、单一连续分配
内存在此方式下分为系统区和用户区,系统区仅提供给操作系统使用,通常在低地址部分;用户区是为用户提供的,除系统区之外的内存空间。这种方式无需进行内存保护,但只能用于单用户、单任务的操作系统。
2、固定分区分配
将内存划分成若干个固定大小的区域。
1、等长分区:
若进程大于分区则只能部分载入,要应用覆盖技术;小进程将产生内部碎片,导致内存利用率低;
放置算法:进程可以放到任意一个可用分区中。
2、不等长分区:
放置算法:
- 多队列:为每个分区设立一个输入队列,各个队列中的进程只能使用对应的分区(以把每个进程分配到能够容纳它的最小分区为目的);
- 单队列:进程使用可容纳它的最小空闲分区;
3、优缺点:
- 相对简单,开销小;
- 分区数目预设,限制了活动进程的数量;
- 分区大小预设,小进程不能充分利用其占有的空间;
3、动态分区
动态分区分配又称为可变分区分配,是一种动态划分内存的分区方法。这种分区方法不预先将内存划分,而是在进程装入内存时,根据进程的大小动态建立分区,使得分区的大小正好适合进程的需要。
存在的问题:
- 外部碎片:内存中出现的许多小的内存块(不连续),使得内存利用率下降;
- 可以采用压缩移动进程使它们相互紧靠的方法消除碎片(相当耗时且需要进行动态重定位);
放置算法:
- 首次适配(first fit)算法:从前端开始扫描内存,直到找到一个足够大的空闲区;(最好、最快)
- 下次适配(next fit)算法:从上次分配结束的地方开始扫描内存,直到找到一个足够大的空闲区;
- 最佳适配(best fit)算法:扫描整个内存,找出一个足够大的最小空闲区;(性能通常是最差的)
3、伙伴系统(buddy system)
针对于固定分区和动态分区的折中方案:
- 可用的内存块大小为2^k ,L<=k<=U(最小块大小为2^L,最大块大小为2^U);
- 初始空间是大小为2^U的块;
- 请求一块内存S时,首先寻找一块最小的可满足S的内存块M,若S*2<=M则将M均分为两块M1和M2,再取其中任意一块与S进行比较,做同样的操作直到不可再均分,最后给S分配一个均分到最小程度的块。
- 释放内存后若被释放的块的伙伴未被分配,则将两者合并。
一个例子:
四、页式存储管理
页式存储管理采用不连续的分配方式,主要解决了分区存储管理造成内存碎片的问题。
是在操作系统加载时完成分页的,对用户不可见。
1、基本原理
- 将主存划分成许多等长的帧(frame,页框);
- 将进程划分成若干大小相同的页,一个页的大小与一个帧的大小相等;
- 进程加载时,所有页面被载入可用帧,同时建立页表(分页的主要数据结构)来标记不同页的偏移地址。(即进程中的页指定到内存中的页框的位置)
上面图示说明了分页管理相比于分区管理的好处——减少了内存的浪费。
2、页表
操作系统通过页表的建立和维护进行内存管理。
- OS为每个进程建立并维护一个页表;
- 页表的每个表项包含该页在内存中对应的帧号及其他信息;
- 页表以页号为索引;
- OS另外还维护一个空闲帧的列表;
- 页对齐:保证指令的完整性,使得一条指令不会被分割到不同的页(编译器保证了页对齐);
上图对应于再上面的一张图。
3、简单分页中的重定位
- 程序中的逻辑地址由两部分组成:页号、页内偏移;
- CPU的一对寄存器记录当前运行进程的页表起始物理地址、页表长度;
- 页号,偏移 转换为 帧号,偏移;(页号从0开始计数)
- 规定页(帧)的大小必须为2的整数次幂;
延续上面的例子,考虑一个n+m的位的地址,则最左边的n位是页号(相对于进程来说的页号,是进程页表的索引),最右边的m位是偏移量。则地址转换步骤为:
- 提取页号,即逻辑地址最左面的n位;
- 以这个页号为索引查找该进程页表中对应的页表项得到该页对应的页框号k;
- 该页框的起始物理地址为k*2^m,被访问字节的物理地址是这个起始地址加上偏移量。
4、与分区管理的区别
- 页帧非常小,从而内部碎片即使存在也很小;
- 一个进程可占用多个页帧,不需要覆盖;
- 不要求一个进程连续占用的多个页帧;
5、存在的问题:
- 不易实现共享和保护(事先不知道程序的逻辑组织)
- 不便于动态链接;
- 不易处理数据结构的动态增长(若某一页中的数据增长后超过一页的范围就麻烦了);
五、分段存储管理
分段可以消除内部碎片,但和动态分区一样,会产生外部碎片,不过由于进程被分成多个小块,所以外部碎片也会很小。
且分段对程序员来说通常是可见的,并且可以作为组织程序和数据的一种手段。
1、基本原理
- 将程序及数据划分成若干段,不要求等长,但不能超过最大长度;
- 进程加载时,所有段被载入内存可用区域,不要求连续,同时建立段表;
2、段表
- OS为每个进程建立并维护一个段表;
- 段表的每个表项包含该段在内存中对应的起始物理地址、段长等;
- 段表以段号为索引;
- OS另外还维护一个内存空闲块的列表;
3、简单分段中的重定位
逻辑地址由段号和偏移量组成;
进程进入运行态时其段表地址被载入CPU专用寄存器;
考虑一个n+m位的逻辑地址,最左边的n位是段号,最右边的m位是偏移量:
- 提取段号,即逻辑地址最左面的n位;
- 以这个段号为索引查找该进程段表中该段的起始物理地址、段最大长度;
- 最右边m位表示偏移量,偏移量和段长度进行比较,如果偏移量大于该段的长度,则这个地址无效;
- 物理地址为该段的起始物理地址与偏移量的和;
六、页式管理和段式管理的比较
- 分页是基于系统管理的需要,分段是基于用户应用的需要;
- 页大小是固定的;段大小通常是不固定的,不利于虚拟存储;
- 分页是一维的,各个模块在连接时必须组织成同一个地址空间(页号连续,页帧不一定连续),而分段是二维的,各个模块在连接时可以每个段组织成一个地址空间(段号可以不连续);
- 分段克服了分页存在的问题,反应了程序的逻辑组织,易于实现保护和共享、便于动态连接和数据结构的动态增长;
- 分段存在外部碎片,分页只有小的内部碎片,所以分页内存利用率比分段高;
- 综上,分段用于内存保护,分页用于虚拟存储。
七、此部分的一些概念性知识
- 内存管理:操作系统对内存的划分和动态分配。
- 重定位:程序在运行时将要执行的指令的逻辑地址转为物理地址。
- 逻辑组织:操作系统可执行的程序的结构。
- 物理组织:程序在内存中的存放结构。
- 交换技术:进程在内存与外存之间的动态调度。
- 固定分区分配:将内存划分成若干个固定大小的区域。(内部碎片)
- 动态分区分配:在进程装入内存时根据进程的大小动态建立分区。(外部碎片)
- 外部碎片:还没被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。
- 内部碎片:程序装入到固定大小的分区时其所需空间小于分区大小导致分区剩余的空间无法被系统使用,这一部分剩余的空间则称为内部碎片。