存储器管理
存储器管理
程序的装入和链接
将一个用户源程序变为一个可在内存中执行的程序,有以下步骤:
- 编译:编译程序将用户源代码编译成若干目标模块
- 链接:链接程序将编译后的目标模块和它们所需的库函数链接成一个完整的可装入模块
- 装入:装入程序将装入模块装入内存
程序的链接
根据链接的时间,可以分为下面三种:
- 静态链接:在程序运行以前进行链接的方式
- 装入时动态链接:在装入内存时,边装入边链接的方式
- 运行时动态链接:在程序执行中需要目标模块时,才对它进行链接。
程序的装入
将一个装入模块装入内存,有绝对装入
,可重定位装入
和动态运行时装入
三种方式
- 绝对装入方式:直接将目标模块装入到内存指定的位置(具体的物理地址),只适合单道程序环境。
- 可重定位装入方式:因为装入的模块使用的是逻辑地址,与实际装入内存的物理地址不同,因此在装入时进行一次重定位(对目标程序中的指令和数据进行修改,因为装入后变换过的地址不会再次改变,因此也称作静态重定位)。
- 动态运行时装入:在程序装入内存后并不会立即把装入模块中的相对地址转换为绝对地址,而是将地址转换推迟到程序真正执行时才进行。
连续分配方式
指的是为一个用户程序分配一个连续的内存空间。连续分配方式又可以分为单一连续分配、固定分区分配、动态分区分配、动态重定位分区分配四种方式。
- 单一连续分配:内存被分为系统区和用户区,这种方式就是将用户程序直接全部分配到用户区中。只能用于单用户、单任务的操作系统中。
- 固定分区分配:将内存用户空间划分为若干固定大小的区域,每次在一个分区中只转入一道作业。不同分区的几道作业可以并发运行,这是最简单的一种多道程序的存储管理方式。
- 动态分区分配:根据进程的实际需要,动态为之分配内存空间。
这种方式需要系统配置空闲分区表或空闲分区链来描述空闲分区和已分配分区的情况。 - 可重定位分区分配:如果当前系统中只有若干小的分区,虽然它们的容量总和大于要装入的程序,但因为这些分区不相邻,无法将程序装入内存。
为了解决这个问题,动态重定位就是通过将内存中所有作业进行移动,让它们全部相邻,从而将多个小分区拼接成一个大分区。
但此时需要对程序和数据的地址进行变换,并且需要硬件的支持,即在系统中增加一个重定位寄存器,用来存放程序在内存中的起始地址。
对换
指的是把内存中暂时不能运行的进程或暂时不用的程序和数据调度到外存上,以腾出足够的内存空间,再把已具备运行条件的进程或进程所需的程序和数据调入内存。
如果对换的单位是进程,则称为“进程对换”(”整体对换“);如果对换的基本单位是“页”或“段”,则分别称为“页面对换”和“分段对换”,两者又统称为“部分对换”。
优点:提高了内存利用率。
段页存储
连续分配方式会形成许多内存碎片,虽然可以通过“紧凑”的方法将它们拼接成大块空间,但这样开销很大,因此有了离散分配的方式,也就是将一个进程直接分散地装入许多不相邻的分区中。如果离散分配的基本单位是页,则称为分页存储管理方式;如果基本单位是段,则称为分段存储管理方式。
基本分页存储管理
在分页存储管理方式中,如果不具备页面对换功能,则称为基本的分页存储管理方式(纯分页存储管理方式),它不具有支持实现虚拟存储器的功能,要求把每个作业全部装入内存后才能运行。
引入目的
分页是动态分区分配的发展结果,两者目的都是提高内存利用率。
优点
便于构造页表,易于管理,不存在外部碎片。
1.页面与页表
页面
分页存储管理是将一个进程的逻辑地址分为若干大小相等的片,称为页面或页,并为各页加以编号(从0开始)。相应地,也把内存空间分为与页面大小相同的若干存储块,称为(物理)块或页框,同样为它们编号(从0#块开始)。在为进程分配内存时,以块为单位将进程中若干页分别装入多个不相邻的物理块中。由于进程的最后一页经常装不满一块而形成了不可利用的碎片,称之为“页内碎片”。
页面的大小应选择适中,并且是2的幂,通常是512B~8KB。
地址结构
分为页号P和位移量W。
页表
在分页系统中,允许将进程的各个页离散地存储在内存不同的物理块中,但系统应能保证进程的正确运行,为了能在内存中找到每个页面所对应的物理块,系统又为每个进程建立了一张页面映像表,简称页表。
页表的作用是实现从页号到物理块号的地址映射。它存放在内存中。
CPU每存取一个数据都需要两次访问内存。第一次访问内存中的页表,通过地址变换机构获取到指定页的物理块号后,再将块号和页内偏移量拼接形成物理地址。第二次从第一次所得的物理地址中存取数据。
2.两级和多级页表
现代大多数计算机都支持非常大的逻辑地址空间(232~264),这样页表就会非常大。例如:对一个有32位逻辑地址空间的分页系统,规定页面大小为4KB,则每个进程中的页表项会达到1MB个。而每个页表项占用1字节,所以仅仅每个进程的页表项就会占用1MB的内存空间,而且还要求是连续的,显然不可能实现。
解决办法:
-
采用离散分配方式来解决难以找到一块连续的大内存空间的问题。
具体来说就是增加一级或多级页表,外层页表中存放的是下一级页表所在的物理块号。这样一来只需要第一级页表需要连续,而后面几级页表就都可以离散分配了。
-
只将当前需要的部分页表调入内存,其余的页表仍留在磁盘上,需要时再调入。
在进程运行时,如果需要的页表尚未调入内存,就会产生中断信号,请求OS将磁盘上的该页表分页调入内存。
基本分段存储管理
引入分段存储管理的目的
主要是为了满足用户(程序猿)编程和使用上多方面的要求。
优点(具体满足了用户以下需求):
- 方便编程
- 信息共享
- 信息保护
- 动态增长
- 动态链接
1.分段
作业的地址空间被分为若干个段,每个段是按照程序的自然分界划分出的长度可变的区域,每个段定义了一组逻辑信息。例如:主程序段MAIN、数据段D、堆栈段S等。段的逻辑地址由段名(段号)和段内偏移量(段内地址)组成。
2.段表
和页表类似,为了让不同的段可以离散地放在内存中不同的分区中,系统为每个进程建立了一个段表,它占用一个连续的内存空间,记录了每个段在内存中的起始地址和段的长度。也就是说段表的作用是实现从逻辑段到物理内存区的映射。
分页和分段的区别和联系
联系
两者都是离散分配方式,而且都要通过地址映射机构来实现地址变换
地址映射机构作用:实现从用户地址空间的逻辑地址到内存空间中物理地址的变换功能。
区别
- 满足的需要不同:分页为了满足系统管理的需要;而分段是为更好地满足用户的需要
- 大小是否固定:页的大小固定且由系统决定;而段的大小不固定,主要取决于所写的程序。
- 地址空间维度不同:分页的作业地址空间是一维的,每个页是单一的线性地址空间;而分段的地址空间是二维的,一个地址由段名和段内偏移量组成。
段页式存储管理方式
分页和分段存储管理方式各有优缺点。分页系统能有效提高内存利用率;而分段系统能更好满足用户需要。而段页式存储管理方式就是二者的结合。
基本原理
先将用户程序分为若干个段,并且每个段赋予一个段名;再将每个段分为若干个大小相等的页。
优点
用分页的方式来管理实际存储空间,但每个段又可以满足用户需要(信息共享和信息保护,动态增长等)。
缺点
如果地址变换机构中的高速缓冲寄存器没有找到该表项,就需要三次访问内存才能获取最终的物理地址。
第一次检索内存中的段表,从中获取页表的起始地址;第二次访问内存中的页表,从中取出物理块号以获取物理地址;第三次才真正从前面所得的物理地址获取指令或数据。
虚拟存储器
前面的各种存储器管理方式都需要将一个作业全部装入内存后才能运行,但如果遇到一个很大的作业或大量作业需要运行的情况,可能就会出现内存容量不足以容纳这个或这些作业的情况。
一种显而易见的解决办法就是从物理上增加内存容量,例如安装一个额外的内存条;而另一种方法就是从逻辑上扩充内存容量,这就是虚拟存储器的作用。
这种技术的理论支持就是局部性原理,也就是在程序运行时的较短的一个时间内,程序的执行仅局限于某个部分;访问的存储空间也局限于某个区域。
定义
虚拟存储器指有请求调入和置换功能,能从逻辑上对内存容量进行扩充的一种存储器系统。它建立在离散分配的存储管理方式的基础上。
具体实现方法
基于局部性原理,应用程序在运行前,只需要将当前要运行的少数页面或段先装入内存即可运行,其余的部分暂留在盘上。在程序执行期间,如果要访问的页/段尚未调入内存,就通过OS的请求调页/段功能将其调入内存。如果此时内存已满,还须页/段的置换功能将内存中暂时不用的页/段调到盘上,再将要访问的页/段调入内存。
常见的实现方式有:请求分页存储管理方式和请求分段存储管理方式。
页面置换算法
一个好的页面置换算法,应具有较低的页面更换频率。从理论上讲,应将那些以后不再会访问的页面换出,或把那些在较长时间内不会再访问的页面调出。
最佳置换算法
每次选择的被淘汰的页面是以后永不或在未来最长时间内不再被访问的页面。它可以保证获得最低的缺页率。
先进先出页面置换算法
淘汰最先进入内存的页面,也就是选择并淘汰在内存驻留时间最久的页面。
最近最久未使用置换算法
根据页面调入内存后的使用情况,选择并淘汰最近最久未使用的页面。
Clock置换算法(最近未用算法)
这是一种和LRU近似的算法。
简单Clock算法:只需要为每页设置一位访问位,内存中所有的页面都通过指针链接成一个循环队列。当某页被访问时,访问位置1。算法通过循环检查链表中页的访问位,如果当前指向的页的访问位是0就将该页换出;若为1,则置0。