根据冯·诺依曼原理,程序必须先存储在内存中,才可以执行。
在多道程序并发执行的系统存储器管理非常重要。
5.1 存储器管理的功能
5.1.1 主存分配与回收
要完成内存的分配和回收工作,要求设计者选择和确定几种策略和结构:
1.调入策略
用户程序在何时调入内存的策略。
目前有请调和预调两种。
2.放置策略
用户程序调入内存时,确定将其放置在何处的策略。
3.置换策略
当需要将某个用户程序调入内存而内存空间又不够时,就要确定哪个或哪些程序可以从内存中移走。
4.分配结构
分配结构是用来登记内存使用情况的数据结构。
5.1.2 地址映射(地址重定位)
内存的每个存储单元都有一个编号,这种编号称为内存地址(或称为物理地址,绝对地址)。
内存地址的集合称为内存空间(或物理地址空间)。
要求用户用内存地址编程是非常困难的,尤其是在多道程序设计的环境中。用户编程所用的地址称为逻辑地址(或程序地址,或虚地址),由逻辑地址组成的空间称为逻辑地址空间(或程序地址空间)。
用户程序装入内存时对有关指令的地址部分的修改(从程序地址到内存地址的地址映射)称为地址重定位。
5.1.3 内存保护
保证在内存中的多道程序只能在给定的存储区域内活动并互不产生干扰。
防止地址越界
防止越权(对共享区有访问权)
硬件支持:
界地址寄存器(界限寄存器)
界地址寄存器被广泛使用的一种存储保护技术
机制比较简单,易于实现
5.1.4 主存扩充(虚拟内存)
为了使程序员在编程时不受内存的结构和容量的限制,系统为用户构造一种存储器,其结构可能与内存结构不同,容量可能远远超过内存的实际容量。
这种面向编程的存储器称为虚拟存储器。由虚存构成的存储空间称为虚存空间,或称虚地址空间。
5.2 存储器的层次结构
5.3 程序的装入与链接
1.用户程序变为可执行程序需要经过:编译、链接、装入;逻辑地址、物理地址
2.程序的装入:绝对装入、可重定位装入、动态运行装入;重定位、静态重定位、重定位寄存器
3.程序的链接:静态链接、装入时动态链接、运行时动态链接
用户源程序执行通常要经过的步骤:
(1)编译:由编译程序将用户源代码编译成若干个目标模块。
(2)链接:由链接程序将编译后形成的目标模块以及它们所需要的库函数,链接在一起,形成一个装入模块。
(3)装入(加载):由装入程序将装入模块装入主存的过程。
5.3.1 程序的装入
把程序装入内存空间。采用三种方式:
1.绝对装入方式(Absolute Loading Mode):在可执行文件中记录内存地址,装入时直接定位在上述(即文件中记录的地址)内存地址。
优点:装入过程简单。
缺点:过于依赖于硬件结构,不适于多道程序系统。
2.可重定位方式(Relocatable Loading Mode):在可执行文件中,列出各个需要重定位的地址单元
和相对地址值。当用户程序被装入内存时,一次性实现逻辑地址到物理地址的转换,以后不再转换(一般在装入内存时由软件完成)。 即装入时根据所定位的内存地址去修改每个重定位地址项,添加相应偏移量。
静态重定位:地址变换在进程装入时一次完成,以后不再改变
优点:不依赖于硬件,可以装入有限多道程序;无须硬件支持。
缺点:一次性全部装入;一个程序通常需要占用连续的内存空间;程序装入内存后运行时不能移动。
说明:重定位表中列出所有修改的位置。如:重定位表的150表示相对地址150处的内容为相对地址(即100为从0起头的相对位置)。在装入时,要依据重定位后的起始位置(2000)修改相对地址。
地址单位修改:重定位表中的150->绝对地址2150 (=2000+150)
相对地址值修改:内容100变成2100(=2000 +100)
3.优点:动态运行时装入方式(Dynamic Run-time Loading):在装入模块装入主存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种地址转换推迟到程序要真正执行时才进行。实现时需要重定位寄存器。
优点:不需要一次装入;OS可以将一个程序分散存放于不连续的内存空间,可以移动程序。
缺点:需要硬件支持,OS实现较复杂。它是虚拟存储的基础。
5.3.2 动态运行时装入方式(Dynamic Run-time Loading)
在装入模块装入主存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种地址转换推迟到程序要真正执行时才进行。实现时需要重定位寄存器。
优点:不需要一次装入;OS可以将一个程序分散存放于不连续的内存空间,可以移动程序。
缺点:需要硬件支持,OS实现较复杂。它是虚拟存储的基础。
静态链接 (Static Linking):程序运行前将目标模块以及他们所需的库函数链接成为一个完整的装配模块,以后不再拆开。
动态链接 (Dynamic Linking):在装入或运行时进行链接。 通常被链接的共享代码称为动态链接库 (DLL, Dynamic-Link Library)或共享库(shared library)。
优点:共享、部分装入、便于局部代码修改、便于运行环境适应
缺点:链接开销:增加了程序执行时的链接开销;管理开销:程序由多个文件组成,增加管理复杂度。
5.4 连续分配方式
连续分配方式是指为一个用户程序分配一个连续的内存空间。
5.4.1 单一连续分配
最简单,适用于单用户、单任务的OS。
单道程序环境下,内存分为两个区域:系统区、用户区。应用程序装入到用户区,可使用用户区全部空间。系统区提供给OS使用。
优点:易于管理。
缺点:对要求内存空间少的程序,造成内存浪费;程序全部装入,很少使用的程序部分也占用内存。
5.4.2 固定分区分配
管理思想:把内存固定地划分为若干个固定大小区域,每个分区装入一道作业。分区的划分可采用分区大小相等和不等两种方式。
分区大小通常由计算机操作员或由操作系统给出,并维护分区使用表,包含每个分区的起始地址、大小及状态。当用户程序需装入内存时,检查分区使用表,如果有可用的满足要求的分区,则分配,并置该分区状态为“已分配”;否则不给该程序分配内存。
例如:某系统的内存容量为256K,操作系统占用低地址的20K,其余空间划分成4个固定大小的分区。
固定分区分配的性能分析:在作业大小和出现频率均已知的情况下,固定分区是合适的。在这种情况下分区的大小选择与作业大小相当,这样内存的使用效率较高。但是若作业的大小和出现的频率不知道时,势必造成分区的大小和作业的大小相差甚远,这样就会造成存
储空间的浪费,从而影响整个系统的效率。
优点:易于实现,开销小。
缺点:内存碎片造成浪费;分区总数固定,限制了并发执行的程序数目。
5.4.3 动态分区分配(可变分区分配)
动态分区分配是指根据进程的实际需要,动态地为之分配内存空间。这种存储管理的方法解决了固定分区严重浪费内存的问题。是一种较为实用的存储管理方法,涉及到分区分配中的数据结构\分区分配算法\分区的分配回收问题。
1.实现动态分区需要的数据结构
在动态分区存储管理中,要有相应的数据结构来登记空闲分区的说明信息,它包括空闲分区的大小和位置。
不同系统根据设计要求采用不同的结构。
常用的有空闲分区表和空闲分区链结构。
系统还要设置了等待分区队列,当系统中无空闲区或无满足要求的空闲区时,则把申请者送入等待队列中,等待别的进程释放内存之后再唤醒队列中的进程。
2.动态分区分配算法
准备工作:
按空闲区首址递增的次序归类组织空闲分区表或空闲分区队列;
按空闲区大小的递增或递减次序组织空闲分区表或队列。
(1)首次适应算法(first-fit)
要求空闲分区按首址递增的次序组织空闲分区表(队列)。
分配:
当进程申请大小为SIZE的内存时,系统从空闲区表的第一个表目开始查询,直到首次找到等于或大于SIZE的空闲区。从该区中划出大小为SIZE的分区分配给进程,余下的部分仍作为一个空闲区留在空闲区表中,但要修改其首址和大小。
回收:
按释放区的首址,查询空闲区表,若有与释放区相邻的空闲区,则合并到相邻的空闲区中,并修改该区的大小和首址。否则,把释放区作为一个空闲区,将其大小和首址按照首地址大小递增的顺序插入到空闲区表的适当位置。
优点:
优先使用低地址空间,因而在高地址的空间可能会保留较大的空闲分区。所以,大进程申请的存储空间大都能在高地址端得到满足。
缺点:
由于每次只简单地使用找到的第一个分区,结果可能导致低址部分不断被使用,将较大的空闲分区不断地分割为较小的空闲分区。每次查找都从地址开始,增加开销。
(2)NF循环首次适应算法(next-fit)
在FF的基础之上,按空闲分区的前后次序,从上次分配的分区起查找(到最后分区时再回到开头),找到符合要求的第一个分区。
该算法的分配和释放的时间性能较好,使空闲分区分布得更均匀,但较大的空闲分区不易保留。
该算法常常会导致内存中缺乏大分区,因为它会均衡地利用空闲分区,包括分割较大的空闲分区。从而使得大进程无法装入内存运行。NF算法可能会导致大量的外零头,需要较频繁地实施“紧凑”操作。
(3)最佳适应法(best-fit )
要求按空闲分区大小从小到大的次序组成空闲分区表(队列)。
分配:
当进程申请一个存储区时,系统从表头开始查找,当找到第一个满足要求的空闲区时,停止查找,并且这个空闲区是最佳的空闲区;
所谓最佳即选中的空闲区是满足要求的最小空闲区,避免了大材小用。
回收:
按释放区的首址,查询空闲区表,若有与释放区相邻的空闲区,则合并到相邻的空闲区中,并修改该区的大小和首址,否则,把释放区作为一个空闲区插入空闲区表。
优点:
在系统中若存在一个与申请分区大小相等的空闲区,必定会被选中。
若系统中不存在与申请分区大小相等的空闲区,则选中的空闲区一定是满足要求的最小空闲区,而不致于毁掉较大的空闲区。
缺点:
空闲区的大小一般与申请分区大小不相等,因此将其一分为二,留下来的空闲区一般情况下是很小的,以致无法使用。随着时间的推移,系统中的小空闲区会越来越多,从而造成存储区的大量浪费
注意:分配和回收后要对空闲区表(队列)按照分区大小重新排序。
(4)最坏适应法(worst-fit)
要求按空闲区大小从大到小的顺序组织空闲区表/队列。
分配:
进程申请一个大小为SIZE的存储区时,总是检查空闲分区表的第一个空闲区的大小是否大于或等于SIZE。若空闲区小于SIZE,则分配失败;否则从空闲区中分配SIZE的存储区给用户,然后修改和调整空闲区表。
回收:
按释放区的首址查询整个空闲分区表/队列。若有与释放区相邻的空闲分区,则合并到相邻的空闲分区中,并修改该分区的大小和首址;否则把释放区作为一个空闲分区插入空闲分区表/队列。
优点:
当程序装入内存中最大的空闲分区后,剩下的空闲分区还可能相当大,还能装下较大的程序;
每次仅作一次查询工作,效率高。
可以避免形成大量较小外零头。
缺点:
它总是分割大的空闲分区。当遇到大进程申请大空间时,无法找到一个足够大的空闲分区。
在大进程面前,内存中所谓的较大空闲分区也是外零头了。
注意:分配回收后要对空闲分区表/队列重新排序。
三种放置策略各有利弊,应针对具体作业序列来分析:
对于某一作业序列,某种算法能将该作业序列中所有作业安置完毕,那么说该算法对这一作业序列是合适的。
对于某一算法而言,如它不能立即满足某一要求,而其它算法却可以满足此要求,则这一算法对该作业序列是不合适的。
基于索引搜索的动态分区分配算法(了解)
(1)快速适应算法:分类搜索法
把空闲分区根据容量大小进行分类,对每一类具有相同容量的空闲分区,设立一个空闲分区表,同时在内存中设立一张管理索引表。
(2)伙伴系统(buddy算法)
伙伴系统内存的用户可用空间为2^m。
系统总是为进程分配大小为2^k的一个空闲分区。其中n≤k≤m,2^n是系统允许的最小分区尺寸。
如果进程申请的存储空间大小为x,可以计算出一个i且2^(i-1)<x≤ 2^i,则将整个2^i大小的分区分配给它(在2^i 中能找到合适的分区)。
若2^i 的分区已经耗尽,则在2^(i+1)分区中去寻找大小为2^(i+1)分区,把该分区被分割成大小相等 2^i的两个分区。这两个分区大小相等,被称为伙伴,则将两个伙伴中的任何一个分配给进程;
若2^(i+1)的空闲分布不存在,则继续向上找更大的分区,此过程一直继续进行,直到产生合适的分区。 最坏情况下可能需要对2^k的空闲分区进行k次分割。
3.动态分区的分配和回收
分区的分配:
系统初启后,除操作系统占用一个分区外,其余存储区为一个大的空闲区。
分区的分配是指系统根据用户的请求,在空闲分区表或空闲分区队列中寻找一个满足用户要求的空闲分区,把这个空闲分区分配给用户。
以空闲分区表为例,当用户要求一个大小为SIZE的存储空间时,系统查询空闲分区表,找一个大于或等于SIZE的空闲区。
分配时的三种情况:
一是系统中无满足要求的空闲分区,则分配失败。
二是空闲区大小与SIZE相等,则修改空闲分区表相应表目,向用户返回该空闲分区首址,表示此空闲分区已分给了要求的用户。
其三是空闲分区大于SIZE,这时将空闲分区一分为二。将一个空闲分区分成二部分有两种办法:
①从空闲分区的上部开始划出SIZE大小的空闲分区给用户;
②从空闲分区的底部开始向上划出SIZE大小的空闲分区给用户。
一般常采用第二种办法,因为这样划分时,余下的部分在空闲分区表中的首地址不变,只需要修改一下大小就行了。
分区的回收:
当某个进程释放某存储区时,系统首先检查释放区是否与系统中的空闲区相邻,若相邻则把释
放区合并到相邻的空闲区中去,否则把释放区作为一个空闲区插入到空闲分区表的适当位置。
回收区域旁边有没有空闲区?那么,回收的内存可能出现四种情况之一:
释放区与前空闲区相邻,分区数不变:将释放区与前空闲区合并为一个空闲区。其首址仍为前空闲区首址,大小为释放区大小与空闲区大小之和。
释放区与前后两个空闲区相邻,分区数减1:将这三个区合为一个空闲区,其首址为前空闲区首址,大小为这三个区大小之和,并取消原后空闲区表目。
释放区与后空闲区相邻,分区数不变:则把释放区合并到后空闲,首地址为释放区首地址,大小为二者大小之和。
释放区不与任何空闲区相邻,分区数加1 :将释放区作为一个空闲区,将其大小和首址插入到空闲区表的适当位置。
由于空闲区大小与申请内存的大小相等的情况是很少的,绝大多数情况是从一个空闲区中切去一块,剩下的部分作为一个空闲区仍留在空闲区表中,随着时间的推移,空闲区的发展趋势是越来越小,直至不能满足任何用户要求。这种不能被任何用户使用的极小的空闲区碎片造成了存储空间的浪费。
4.在分区存储管理中解决碎片的办法
①规定门限值(由操作系统规定,如1K),分割空闲区时,若剩余部分小于门限值,则不再分割此空闲区。
②定期压缩存储空间,将所有空闲区集中到内存的一端(紧凑),但这种方法的系统开销比较大。
5.4.4 动态可重定位分区分配
将相对地址转换为物理地址的工作推迟到程序指令要执行时进行。为了不影响指令的执行速度,必须有硬件地址变换机构的支持:重定位寄存器。
动态重定位分区算法与动态分区算法相同,差别仅在于增加了紧凑功能。
5.5 分页存储管理方式
5.5.1 分页存储管理基本思想
1.程序地址空间
将进程的逻辑地址空间分成若干大小相等的部分,称为页(page)。从0开始编页号,每一页内地址也是相对于0编址的用户程序的划分是由系统自动完成的,对用户是透明的通常,一页的大小为2的整数次幂。
2.内存地址空间(物理地址空间)与页面分配
按系统规定的逻辑页大小将内存空间划分为大小相等的区域,称为块或内存块(物理页面)。从0开始编块号。为进程分配内存空间时,以块为单位,将进程的若干个页分别装入到多个可以不相邻的物理块中。
内存分配:
物理块表:整个系统有一个物理块表,描述物理内存空间的分配使用状况
内存以块为单位进行分配,并按应用程序的页数多少来分配。
页和块的大小相同
进程的最后一页经常装不满一个块,因而会形成不可利用的碎片,称为“页内碎片”
逻辑上相邻的页,物理上不一定相邻。
需要增加新的数据结构
3.页面与页面大小
页太大:浪费;
页太小:页表过长。
页面的大小应适中,大小是2^K,通常是1KB~8KB。进程的最后一页经常装不满一个块,所以会形成不可用的碎片,称为“页内碎片”。
4.地址结构
地址长度为N位,它包含两个部分。地址的高位部分为页号P,高址部分代表了页数;地址的低位部分为页内地址、位偏移量W,低址的位数也代表了每一页的大小 。
例如:若给出的地址为十进制,则用公式:
程序地址/页长 (商为页号P,余数为页内地址d)
P = INT [A/L] d = [A] MOD L
程序地址为2170B, 页长为1KB,则2170/1024可得:商为2,余数为122。即P=2,d=122
5.页表
若将应用程序的包含页号和页内地址的逻辑地址转换成内存地址,必须要有一个数据结构,用来登记页号和块号的对应关系和有关信息,这样的数据结构称为页表。页表的作用是实现从页号到物理块号的地址映射。
系统为每个进程在内存建立一个页表,页表内容:
页号:登记程序地址空间的页号
块号:登记相应的页所对应的内存块号
其它:登记与存储信息保护有关的信息
页表的首地址和长度存于该进程的PCB中;占用处理机的当前进程的页表首地址和长度需要放在地址映射机构的页表首址寄存器和页表长度寄存器。
例:作业1有2页分别装入内存的5、6号块;作业2有3页装入内存的2、4、7号块;作业3有1 页装入内存的8号块。
分页中的地址映射其实与通常的地址映射的概念是一样的,即把程序地址转换成内存地址,这个转换过程是在程序执行过程中完成的,是动态地址映射。
5.5.2 地址变换机构
1.地址变换
地址变换机构的任务是将逻辑地址中的页号转变为物理地址中的块号,这个任务借助于页表来实现。页表驻留在内存,在系统中只设一个页表寄存器PTR,其中存放着页表在内存中的始址和页表长度,页表的始址和页表长度存放在本进程的PCB中。页表功能由一组专门的寄存器来实现。
在现代计算机系统中,由系统提供的地址映射硬件(页表寄存器)来完成地址映射工作。
硬件机制,实现逻辑地址到物理地址的转换分页系统中的地址变换过程如下:
(1)根据逻辑地址,计算出页号和页内偏移量;
(2)用页号检索页表,查找指定页面对应的块号;(进行越界判断)
(3)根据块号和页内偏移量,计算出物理地址。(页表始址与页号和页表项长度的乘积相加,得到该表项在页表中的位置,从中得出该页的物理块号,将之装入物理地址寄存器中)
例:某系统采用分页存储管理策略,拥有逻辑空间32页,每页2KB,拥有物理地址空间1MB
1.写出逻辑地址的格式
32=2^5(页号5位)
2K=2^11(页内地址11位)
逻辑地址共16位:0-10位(页内地址)11-15位(页号)2.物理地址空间可以分为多少个内存块
1M=1024K=220
每个块的大小:2^11
所以,物理地址空间可以分为2^9 个内存块
3.每个进程的页表最多拥有多少页表项
每个进程最多拥有32个页面,进程的页表项最多为32项
例:已知某分页系统,主存容量为64KB,页面大小为1K,对一个4页大小的作业,其页面对应关系如下图所示。请将十进制的逻辑地址1023、2500、3500、4500转换成为物理地址。
1.1023/1k 得到页号为0,页内地址为1023查找页表对应块号2,物理地址:2*1k+1023=3071
2.2500/1k 得到页号为2,页内地址为452查找页表对应块号6,物理地址:6*1k+452=6596
3.3500/1k 得到页号为3,页内地址为428查找页表对应块号7,物理地址:7*1k+428=7596
4.4500/1k 得到页号为4,页内地址为404页号大于了页表长度,产生越界中断。
2.分页存储管理中的信息保护
信息保护从两个方面实现:
①在分离程序地址的页号和页内地址时判别访问地址是否越界
若产生的页号满足下式为合法: 0 ≤页号<程序地址空间的页数
判断由硬件自动做,若不合法,硬件产生越界中断,由操作系统的越界中断处理程序进行处理。
②判断访问是否越权
在页表中增加用于存取控制和存储保护的信息,当要访问某页的某个逻辑地址时系统要根据该页的存取控制和存储保护信息检查访问是否合法。
3.快表/联想寄存器
在前述的页地址变换过程中有一个问题,每一次对内存的访问都要访问页表,页表是放在内存
中的,也就是说每一次访问内存的指令至少要访问两次内存,运行速度要下降一半。
解决方法:
把页表放在一组特殊的高速缓冲寄存器中(Cache),从而加快访问内存的速度。
把这种快速存储器组成的页表称为快表,把存放在内存中的页表称为慢表。快表又叫联想存储器( associativememory)或TLB (Translation lookaside buffers)。
快表的大小:
实际上并不需要一个很大的快速存储器,有一个能存放16-512个页表表目的快速存储器就够了。硬件根据需要将页表中当前需要的少量表目读入快表,其它表目仍留在内存的页表中,当需要时读入新的表目,并淘汰适当的表目。
快表性能分析:
当调度合理时,从快表中能找到所需页表项的概率可以达到可以达到90%以上。访问快表的速度是内存速度的数倍或数十倍,那么相对于真正的访问内存工作来讲,访问快表的时间可以忽略不计。
具有快表的页地址变换不会造成进程运行速度的下降。
引入了快表,CPU访问数据所化的时间明显减少
5.5.3 两级页表和多级页表
页表需要连续空间存储的,但是当页表项很多时,仅采用一级页表需要大片连续空间。可将页表分页,并对页表所占的空间进行索引形成外层页表,由此构成二级页表。更进一步可形成多级页表。
将页表进行分页,使每个页面大小与内存物理块大小相同,离散地将各个页面分别存放在不同的物理块中。再建立一张外层页表。
在页表的每个表项中存放的是某页在内存中的物理块号;
在外层页表中的每个页表项中存放的是某页表分页的首址
反置页表(了解):
为每一个物理块设置一个页表项,并将它们按照物理块的编号排序, 其中的内容是页号和所属进程的标识符。进行地址转换时,根据进程标识符和页号去检索反置页表。若能检索到与之匹配的页表项,则该页表项中的序号就是该页所在的物理块号,然后与页内地址一起构成物理地址送入内存地址寄存器;若未能找到,则表明此页还未进入内存。
5.6 分段存储管理方式
5.6.1 为什么要引入分段存储
程序一般都可以分为若干个段,每个段都是一个相对独立的逻辑单位,分段存储更符合用户和程序员的需求:
方便编程:用户按逻辑关系来划分若干个段
信息共享:段是可以信息共享的逻辑单位
信息保护:以信息的逻辑单位为基础
动态增长:
动态链接:以段作为动态链接的基本单位
5.6.2 分段存储管理基本思想
程序地址空间
按程序自身逻辑关系划分为若干个段,每个段都有一个段号;段号从0开始;每段段内从0开始编址,段内地址连续。各段长度不相等,段长由相应逻辑信息组的长度决定
逻辑地址
内存地址空间
内存空间被动态的划分为若干个长度不相同的区域,称为物理段;每个物理段由起始地址和长度确定。
内存分配
以段为单位分配内存,每一个段在内存中占据连续空间;各段之间可以不连续存放。
段地址映射
1.地址映射数据结构
每一进程有个段表,它的每一个段在段表中占用一个表目,记录了该段在内存中的起始地址和段长度;
段表包括有段的首址、段的长度和存取状态等信息。
段表可以存放在一组寄存器中,以此提高地址转换速度。
常见的是将段表放入内存。
段表首址指针和段表的长度存放在进程PCB中。
段表是用于实现从逻辑段到物理内存区的映射的。
2.段地址映射由硬件地址变换机构完成,在系统中设置了段表寄存器,用于存放段表始址和段表长度TL。
当创建进程,将进程的程序和数据装入内存时,系统为之建立段表,并将段表的起始地址填入进程的PCB中。
段表应该被保存在内存中。
当进程被调度执行时,取出其PCB中的段表首址,填入段表寄存器中。
段表寄存器 :实现快速地址变换,用来存放当前执行进程的段表在物理内存中的起始地址。
地址变换
(1)根据逻辑地址中的段号检索进程段表,获得指定段对应的段表项;
(2)判断是否地址越界。比较逻辑地址中的段内偏移量与段表项中的段长,若超过段的长度,则产生存储保护中断(该中断将由操作系统进行处理);否则,转(3);
(3)把逻辑地址中的段内偏移量与段表表项中的段基址相加,从而得到物理地址。
存储保护
防止越界访问:
段号 S<TL
段内地址D<SL
防止越权访问
快表
在分段系统中,为了访问内存中的一条指令或数据,仍然需要两次访问内存:
第一次,访问内存中的段表,获得对应段的起始地址。根据段的起始地址和段内偏移量,计算出物理地址。
第二次,根据物理地址,访问对应存储单元的指令或数据。
同页地址变换一样,在段地址变换过程中,也有两次访问内存的问题。为了加快访问内存的速度也可采用快速存储器组成快表,用于保存最近使用过的段表项。
分段与分页技术的比较
页是信息的物理单位,段是信息的逻辑单位。分页是出于系统管理的需要,分段是出于用户应用的需要。
一条指令或一个操作数可能会跨越两个页的分界处,而不会跨越两个段的分界处。
页大小是系统固定的,段大小通常不固定。通常段比页大,因而段表比页表短,可以缩短查找时间,提高访问速度。
地址表示:
分页是一维的,各个模块在链接时必须组织成同一个地址空间;
分段是二维的,各个模块在链接时可以每个段组织成一个地址空间。
5.6.3 信息共享
段的共享比页的共享更容易。
可重入代码:允许多个进程同时访问的代码,不允许任何进程对它进行修改。
段式存储管理方案
优点:便于共享;便于动态链接
缺点:产生碎片
5.7 段页式存储管理方式
5.7.1 段页式存储管理基本思想
程序地址空间
按段式划分:对用户来讲,按段的逻辑关系进行划分;
按页划分:对系统讲,按页划分每一段
逻辑地址
先将用户程序分为若干个段,再将段分成若干个页
系统需要同时配置段表和页表
内存地址空间
按页式存储管理方案;内存分配以块为单位进行分配。
段表与页表
用于管理的数据结构:段表、页表
5.7.2 地址变换
段表:需要配置段表寄存器。记录了每一段的页表始址和页表长度
进行地址变换时,首先利用段号S将它与段长TL进行比较S<TL,利用段表始址和段号来求出该段所对应的段表项在段表中的位置,从中得到该段的页表始址
页表:记录了该段中每个逻辑页号与内存块号的对应关系
地址变换过程:
首先,从段表寄存器从获得进程段表的起始地址,根据该地址,查找进程的段表。
然后,根据逻辑地址指定的段号检索段表,找到对应段的页表起始地址。
再根据逻辑地址中指定的页号检索该页表,找到对应页所在的块号。
最后,用页框号加上逻辑地址中指定的页内偏移量,形成物理地址。
快表:
第一次,访问段表,从中获得该段的页表首址;
第二次,访问页表,从中取出逻辑地址指定的页面所在的页框号,并将该页框号和页内偏移量相加,形成指令或数据的物理地址;
第三次访问内存,根据前面计算的物理地址,取出对应存储单元的指令或数据。
可以在地址变换机构中增设一个高速缓冲寄存器,其中保存最近使用过的页号及其所属的段号。
5.3 对换技术
在多道环境下扩充内存的方法,用以解决在较小的存储空间中运行较大程序时遇到的矛盾。
交换技术被广泛用于小型分时系统中,交换技术的发展导致了虚拟存储器技术的出现。
进程的程序和数据主要放在外存,当前需要执行的部分放在内存,内外存之间进行信息交换(对换)。
把内存中暂时不能运行的进程或者暂时不用的程序和数据换到外存上,以便腾出足够的内存空间。再把已具备运行条件的进程或者进程所需要的程序和数据换入内存。
作用:改善内存利用率;提高处理机的利用率和系统的吞吐量。
这种技术是进程在内存与外存之间的动态调度:
整体对换(进程对换)
部分对换(页面对换、分段对换)
交换技术实现中的几个问题:
1.选择原则将哪个进程换出内存?
例子:分时系统,时间片轮转法或基于优先级的调度算法,在选择换出进程时,换出要长时间等待的进程。
2.对换时机的确定何时需发生交换?
只要不用就换出(或很少再用);
只在内存空间不够或有不够的危险时换出;
3.交换时需要做哪些工作?
①需要一个磁盘交换区:
文件区:占磁盘空间的大部分,目标是提高文件存储空间的利用率,离散分配
交换区:只占磁盘空间的小部分,操作频率高,需要提高换进换出的速度,连续分配
②对换空间的分配与回收
连续分配的方式,与动态分区方式的内存分配与回收类似(FF、NF、BF、WF)
③换出
选择换出进程(阻塞休眠状态、优先级最低、内存驻留时间)
在进程换出时,只能换出非共享的程序和数据段;
申请对换空间成功以后将该进程的程序和数据传送到对换区,然后回收其内存空间,修改PCB。
④换入
找出就绪状态中已换出的进程,选择换出时间最长的进程作为换入进程,进行换入。
4.什么时候需要换入?
处理机正常运行时不需要启动对换程序
如果发现许多进程在运行时经常发生缺页而且明显出现内存紧张的情况,则需要启动对换程序,将一部分进程调至外存;
如果发现所有进程的缺页率都已经明显减少,则可以暂停运行对换程序。