1.02k likes | 1.26k Views
第5章 内存管理. 本章知识点: 5.1 概述 5.2 存储管理的基本技术 5.3 分页存储管理 5.4 分段存储管理 5.5 段页式存储管理 5.6 虚拟内存的置换算法 5.7 系统举例(略). 5.1 概述. 在计算机系统中,内存管理在很大程度上影响着这个系统的性能,这使得存储管理成为人们研究操作系统的中心问题之一。虽然随着硬件技术和生产水平的迅速发展,内存的成本急速下降,但是,内存容量仍是计算机资源中最关键且最紧张的资源。因此,对内存的有效管理仍是现代操作系统中十分重要的问题。. 5.1 概述. 内存
E N D
第5章 内存管理 本章知识点: • 5.1 概述 • 5.2 存储管理的基本技术 • 5.3 分页存储管理 • 5.4 分段存储管理 • 5.5 段页式存储管理 • 5.6 虚拟内存的置换算法 • 5.7 系统举例(略)
5.1 概述 在计算机系统中,内存管理在很大程度上影响着这个系统的性能,这使得存储管理成为人们研究操作系统的中心问题之一。虽然随着硬件技术和生产水平的迅速发展,内存的成本急速下降,但是,内存容量仍是计算机资源中最关键且最紧张的资源。因此,对内存的有效管理仍是现代操作系统中十分重要的问题。
5.1 概述 • 内存 • 内存可以看成是一个由字或字节构成的大型一维数组,每个字或字节都有它们自己的地址,为了加速通常安排字长为16,32 或 64 位。 • 操作系统和(用户)程序要运行都要先装载到内存中。
5.1.1 基本概念 1.存储器的层次 3级存储器结构
5.1.1 基本概念 2.存储管理 在单道程序系统中,存储管理主要就是分配和回收内存区。在多道程序系统中,要求存储管理具有以下主要功能: 空间管理—记录内存单元的使用状态、分配和回收。 地址转换—把逻辑地址转换成物理地址。 内存扩充—用覆盖、交换和虚拟存储技术实现内存的逻辑扩充。 内存保护—保证每个程序在各自的空间正常运行。 内存共享—共享内存中的程序与数据,减少占用空间,提高 内存利用率。
5.1.2 虚拟存储器 虚拟存储器是具有请求调入和交换功能、能从逻辑上对内存容量进行扩充、给用户提供了一个比真实的内存空间大得多的地址空间,在作业运行前可以只将一部分装入内存便可运行的、以逻辑方式存在的存储器。 虚拟存储器的核心,实质上是让程序的访问地址和内存的可用地址相脱离。虚拟存储器最显著的特性是虚拟性,在此基础上它还有离散性、多次性和交换性等基本特征。
source Program 源程序 object Module 目标模块 Linker 连接程序 Compiler 编译程序 Unix 中的 a.out load Module 装载模块 executable in memory 在内存中执行 Loader 装载程序 (运行时) 5.1.3 重定位(地址转换) • 用户程序的处理
5.1.3 重定位 地址转换 • 用户程序在执行前,需要经过好几个步骤(参见前页),用户程序的地址可能有不同的表示形式。 • 源程序中的地址通常以符号的形式表示。 • 例如,a,b,c,sum等等,是一些整形变量的名字。
5.1.3 重定位 • 编译器将转换这些符号地址到可重定位的地址。 • 例如,从本模块开始的第16 字节 • 目标代码连接器或装载器将再次转换这些可重定位的地址到绝对地址 • 例如,转换到物理内存的 74014 单元 • 每次转换就是从一个地址空间到另一个地址空间的映射。
5.1.3 重定位 把地址空间中使用的逻辑地址转换为内存空间中的物理地址的地址转换叫做重定位,也称为地址映射或地址映像。 根据地址转换的时间及采用技术手段的不同,把重定位分为静态重定位和动态重定位两种。
5.1.3 重定位 1. 静态重定位 静态重定位是由专门设计的重定位装配程序来完成的,是在目标程序装入到内存区时由装配程序来一次性完成所有的地址转换。 优点:无需增加地址转换机构 缺点: • 不能实现重新分配内存 • 用户必须事先确定所需的存储量 • 每个用户进程需各自使用一个独立的副本。
内存 + 132 1234 100 108 132 地址空间 0 8 32 + 032 1234 静态重定位 • 例:ADD AX,DS:[32H] • 实现方法 :f(a)=B+a 装入程序
静态重定位 • 装载时的地址转换(1) • 当一个用户程序装载进内存时,一个进程开始了。假定 该进程的逻辑地址是 0 – 100。 • 对这个进程计算它的物理地址 – 假定装载进内存的起始 地址是1000,那么可以说该进程装载到内存空间的物理 地址是从 1000 到 1100。 • CPU 从逻辑地址 0(物理地址 1000)开始执行指令。 • CPU 大约执行到逻辑地址 1(物理地址 1001)…但是 • 一个更高优先级的进程到达
静态重定位 • 装载时的地址转换(2) • CPU 做上下文切换:保存有关当前进程的所有信息到它的 PCB (进程控制块)中。这个信息应该包括在逻辑地址 0(物理地址 1000)的指令已经被执行。 • 当前进程被从内存交换出到磁盘上。 • CPU 执行更高优先级的进程并完成 • CPU 切换回以前的进程 – 该进程被从磁盘交换进内存。 • 现在,如果该进程被装载到位于物理地址 5000 到5100 的内存空间…
静态重定位 • 装载时的地址转换(3) • CPU 继续执行该进程 – 它打开这个进程的 PCB 并开始从 逻辑地址 1(物理地址 1001)执行指令… • 但是现在物理地址 1001 要么是空的、要么被分配给另一个进程。 • 如果在交换进来后,该进程被装载进它以前占据的内存空间(1000 – 1100)那将没有问题。 • 结论:在装载时进行地址转换不允许进程从一个内存段移动到另一个内存段。
5.1.3 重定位 2. 动态重定位 动态重定位是在目标程序执行过程中,在CPU访问内存之前,由硬件地址映射机构来完成将要访问的指令或数据的逻辑地址向内存的物理地址的转换。 优点: 内存的使用更加灵活有效;几个作业共享一程序段的单个副本比较容易;无需用户干预,由系统来负责全部的存储管理。 缺点 : 需附加硬件支持;实现存储器管理的软件比较复杂。
动态重定位 • 运行时的地址转换(1) • 当一个用户程序装载进内存时,一个进程开始了。假定该进程的逻辑地址是 0 – 100。装入到内存的起始地址为1000,在这个阶段不计算程序内的逻辑地址。 • CPU 从逻辑地址0(物理地址1000)开始执行指令。由硬件地址映射机构计算出该逻辑地址被映射到物理地址1000,所以CPU从物理地址1000开始取指令。 • 现在 CPU 大约执行到逻辑地址 1…但是
动态重定位 • 运行时的地址转换(2) • 一个更高优先级的进程到达 • CPU 做上下文切换:保存有关当前进程的所有信息到它的 PCB (进程控制块)中。这个信息应该包括在逻辑地址 0(当前物理地址 1000)的指令已经被执行。 • 当前进程被从内存交换出到磁盘上。 • CPU 执行更高优先级的进程并完成。 • CPU 切换回以前的进程 – 该进程被从磁盘交换进内存。
动态重定位 • 运行时的地址转换(3) • 如果该进程现在被装载到内存中不同的位置(比如说在物理地址的 5000到5100 之间)… 会有什么问题吗? • CPU 继续执行该进程 – 它打开这个进程的 PCB 并开始从逻辑地址1执行指令。硬件地址映射机构计算出现在该逻辑地址被映射到物理地址5001,所以CPU从物理地址5001开始取指令。 • 结论:在运行时进行地址转换允许进程从一个内存段移动到另一个内存段。
内存 内存 + 032 1234 + 032 1234 100 108 132 100 108 132 地址空间 0 8 32 + 032 1234 动态重定位 基地址 寄存器 100 CPU + 装入 程序 032 装入时 运行中
5.2 存储管理的基本技术 最基本的4种存储管理技术是分区法、可重定位分区法、覆盖技术、交换技术 。
5.2.1 分区法 分区管理是满足多道程序设计的一种最简单的存储管理方法。其基本原理是给每一个内存中的进程划分一块适当大小的存储块,以连续存储各进程的程序和数据,使各进程能并发进行。
5.2.1 分区法 1. 固定分区法 固定分区法就是把内存固定划分为若干个不等或相等的区域,划分的原则由系统决定。在整个执行过程中保持分区长度和分区个数不变。 固定分区法管理方式虽然简单,但内存利用率不高且有内碎片。
固定分区 (1)固定分区管理的数据结构 分区说明表(参见图5.5a) (2)分配:根据运行程序所需的最大内存量,按某种分配策略(FF、BF算法)、在分区表中找一个足够大的空闲区分配,并把状态标志置为“1”;若找不到,则拒绝分配内存。 (3)回收:程序运行结束,释放内存;操作系统根据起始地址或分区号在分区表中找到相应的表目,把状态标志置为“0”即可。 (4)适用:任务数确定的多任务系统。
5.2.1 分区法 2. 动态(可变)分区法 动态分区分配是根据进程的实际需要,动态地为它分配连续的内存空间,各个分区是在相应作业装入内存时建立的,其大小恰好等于作业的大小。 (1)可变分区管理的数据结构 为了实现分区分配,系统中设置了相应的数据结构来记录内存的使用情况,常用的数据结构形式有占用区表(UPT)+空闲分区表(FPT)或占用区表+空闲分区链这两种形式。 注:占用区表类似于分区说明表,空闲分区表、空闲分区链参见图5.6、图5.7。
动态(可变)分区 (2)分配:要装入一个程序时,先查看 FPT 或空区链,按某种分配策略(FF、BF、WF 算法)找到一个空闲块分配,并在 UPT 中登记起始地址、大小和状态;若该空闲块分配时剩余较多则剩余部分在 FPT 中登记或插入空区链中,如果所剩很少则一起分配之,FPT 中的状态标志置为“空”。 (3)回收:在 UPT 中把该表目的状态标志置为“空”,回收的分区在 FPT 中登记、或插入空区链中,若有相邻的空闲区则合并后登记。 (4)适用:任务数变化的系统。
合并前 合并后 . . . F1 R . . F2 . . . . . F . . F2 . . 动态(可变)分区 • 回收区 R与空闲区 Fi(i∈1、2、3...)合并问题 第一种情况(有前邻无后邻): 条件:F1.start+F1.length=R.start 结果:F.start=F1.start F.length=F1.length+R.length 新空闲区的起始地址不变、长度变、空闲区数目不变。
合并前 合并后 . . . R F1 . . F2 . . . . . F . . F2 . . 动态(可变)分区 • 回收区 R与空闲区 Fi(i∈1、2、3...)合并问题 第二种情况(无前邻有后邻): 条件: R.start+R.length= F1.start 结果: F.start=R.start F.length=R.length+F1.length 新空闲区的起始地址变、长度变、空闲区数目不变。
合并前 合并后 . . F1 R F2 . . F3 . . . . F . . F3 . . 动态(可变)分区 • 回收区 R与空闲区Fi(i∈1、2、3...)合并问题 第三种情况(既有前邻又有后邻): 条件: F1.start+F1.length=R.start 且 R.start+R.length= F2.start 结果: F.start=F1.start F.length=F1.length+R.length+F1.length 新空闲区的起始地址变、长度变、空闲区数目变(减少)。
. . F1 R . . F2 . . . . F1 F3 . . F2 . . 动态(可变)分区 • 回收区 R与空闲区Fi(i∈1、2、3...)合并问题 第四种情况(既无前邻又无后邻): 这种情况下不存在合并问题,回收的分区作为一个空闲区在相应的数据结构(空闲区表或空区链)中登记即可。 当然空闲区的数目增加。
请求运行的作业序列 P1 600K 10 P2 1000K 5 P3 300K 20 P4 700K 8 P5 500K 15 未分配的 2160K 空闲区 (CPU time) OS 400K 可变分区—分配回收示例 初始时刻为 0,采用 FCFS调度算法
空闲区 260K P3 300K P2 1000K P1 600K OS 400K 可变分区 请求运行的作业序列 P1600K 10 P21000K 5 P3300K 20 P4 700K 8 P5 500K 15 为进程 1, 2, 3分配 还有 260K 未分配
空闲区 260K P3 300K 1000K 空闲区 P1 600K OS 400K 可变分区 请求运行的作业序列 P1600K 10 P2 1000K 5 P3300K 20 P4 700K 8 P5 500K 15 P2 完成,释放 1000K
空闲区 260K P3 300K 300K 空闲区 P4 700K P1 600K OS 400K 可变分区 请求运行的作业序列 P1600K 10 P2 1000K 5 P3300K 20 P4700K 8 P5 500K 15 P4 被分配内存,用了 700K 还有 300K + 260K 未分配, 但是不能为 P5 分配。
空闲区 260K P3 300K 300K 空闲区 P4 700K 600K 空闲区 OS 400K 可变分区 请求运行的作业序列 P1 600K 10 P2 1000K 5 P3300K 20 P4700K 8 P5 500K 15 P1 完成,释放 600K
空闲区 260K P3 300K 300K 空闲区 P4 700K 空闲区 100K P5 500K OS 400K 可变分区 请求运行的作业序列 P1 600K 10 P2 1000K 5 P3300K 20 P4700K 8 P5500K 15 P5 被分配,用了500K。 虽然此时系统中有总量660K的内存,但分为三块,一旦某个作业的内存请求超过300K而小于660K时同样不能运行。
分区管理分配算法 • 分区管理的分配算法关系到空闲区以何种顺序排列。 • 最先适应(FF)算法: 它按顺序选择第一个足以满足请求容量的内存空闲区,而不考虑分配后留下碎片的大小。所以、对 FF 算法空闲区按分区地址递增排列。 • 最佳适应(BF)算法: 它从所有空闲区中找出能满足请求容量的最小空闲区。所以、对 BF 算法空闲区按分区大小递增排列。
分区管理分配算法 • 最坏适应(WF)算法: 它从所有空闲区中找出能满足请求容量的最大空闲区。所以、对 WF 算法空闲区按分区大小递减排列。 • 在可变分区管理中,具体采用何种分配算法最好,还与其它因素有关。BF 算法并非一定是最佳、WF 算法并非一定是最坏。 • 思考:固定分区管理为什么不适合用 WF算法?
分区管理分配算法—示例 • 设内存中有两个空闲区。F1 为 110KB,F2 为 60KB(F1 的地址低于 F2);现依次有 A、B、C 三个作业请求装入运行,它们的内存需求分别是 20K、80K和50K。试描述三种分配算法的效果。 • 若采用 WF 算法: 作业 A 可获得 F1 中的 20K,作业 B 可获得 F1 中的 80K,作业 C 获得 F2 中的50K,三个作业都得到满足。
分区管理分配算法—示例(续) • 若采用 BF 算法: 作业 A 获得 F2 中的 20K,作业 B 获得 F1 中的 80K,而作业 C 的需求无法满足。 • 若采用 FF 算法: 由于 F1 的地址低于 F2 的地址,所以、采用 FF 算法的结果于 WF 算法一样。
5.2.2 可重定位分区法 随着作业不断地装入与撤离,使用动态分区法会出现“外碎片”问题(参见课件的36页),解决碎片问题的方法,是允许程序的位置可动态变化(即程序浮动),采用动态重定位技术可以较好地解决这个问题。 动态重定位分区分配算法,与动态分区分配算法基本上相同;差别仅在于:在这种分配算法中,增加了“紧凑”功能,通常是在找不到足够大的空闲分区来满足用户需求时,进行紧凑处理。
碎片问题 • 碎片: 指不能分配给作业使用的某个无效的存储空间。 • 碎片有内碎片和外碎片之分 • 内碎片: 一个作业内存空间内的无效空间。 • 外碎片: 各个作业所占内存空间外的无效存储空间。
260K 660K P3 300K 300K P3 300K P4 700K P4 700K 100K P5 500K P5 500K OS 400K OS 400K 紧凑(拼接)
紧凑 • 紧凑是有一定条件的 • 如果重定位是动态的、在执行中进行,那么是可以采用紧凑的。 • 紧凑可以消除外碎片,但是它以花费 CPU 时间为代价的。 • 一般在为新作业分配内存时,若无足够大的连续空闲区,但所有空闲区的总量满足请求容量时再紧凑。 • 交换技术可以与紧凑技术结合 • 换出所有要移动的进程,然后再把它们换入。 • (在 MS Windows 中,磁盘碎片整理就是以类似的方式工作,只不过是外存碎片)
存储保护 5.2.2 可重定位分区法 动态重定位的实现过程
5.2.3 覆盖技术 覆盖是在程序运行过程中,把同一存储区在不同时刻分配给不同的程序段或数据段来共享的一种存储分配技术。 使用覆盖从逻辑上扩充内存的示例参见图5.10。 使用覆盖技术时的缺点是程序员必须小心地设计程序及其数据结构,使得要覆盖的段块具有相对独立性,不存在直接联系或相互交叉访问。
5.2.4 交换技术 交换是指将一个进程从内存拷贝到磁盘上,以腾出空间给其他进程使用。需要时,再将该进程调入内存。交换进程由换出和换进两个过程组成,换出是把内存中的数据和程序换到外存的交换区,而换进则是把外存交换区中的数据和程序换到内存的分区中。 在交换系统中,交换所占用的时间相当多。
用户空间 换出 P1 P2 换入 操作系统 内存 磁盘 交换
交换 • 在交换系统中上下文切换时间(关联转换时间)是比较长的。 • 假设用户进程的大小为 1 MB 且标准硬盘(后备存储器)的传输速度为 5MB/s。 • 该进程传入或传出内存的时间为: 1000 KB/5000 KB/s = 0.2 s = 200 ms • 由于要换出和换入,所以总的交换时间至少是 400 ms (0.4 s)。 • 现在,普通的交换用的不多。而修正过的交换在很多系统中被应用。
交换 • 在很多 Unix 版本中,通常交换被设为不使能( disabled )。 • 但是如果有许多进程正在运行并且内存的数量已用到极限,那么交换就会开始。 • 但是如果系统负载减少,那么交换又将停止。