(1)内存管理的基本概念:链接与装入,逻辑地址与物理地址空间,对换与覆盖,重定位
用户程序要在系统中运行,必须先将它装入内存,然后再将其转变为一个可以执行的程序,通常都要经过以下几个步骤:
?1)编译,由编译程序(Compiler)将用户源代码编译成cpu可执行的目标代码,产生了若干个目标模块(Object? Module)(即若干程序段),
2)链接,由链接程序(Linker)将编译后形成的一组目标模块(程序段),以及它们所需要的库函数链接在一起,形成一个完整的装入模块(Load? Module);
3)装入,由装入程序(Loader)将装入模块装入内存。图 4-2 示出了这样的三步过程。
1.程序的装入
无需进行链接的单个目标模块的装入过程中,该目标模块也就是装入模块。在将一个装入模块装入内存时,有如下三种装入方式:
1)绝对装入方式
【不需要进行逻辑地址和物理地址的转换】
当计算机系统很小,且仅能运行单道程序时,采用绝对装入方式。用户程序经编译后,将产生绝对地址(即物理地址)的目标代码。
优点:是CPU执行目标代码快。
缺点:a.是由于内存大小限制,能装入内存并发执行的进程数大大减少 b.编译程序必须知道内存的当前空闲地址部分和其地址,并且把进程的不同程序段连续地存放起来,编译十分复杂。?
因此,通常是宁可在程序中采用符号地址,然后在编译或汇编时,再将这些符号地址转换为绝对地址。? ??
2)可重定位装入方式(静态地址重定位)
【装入后进行逻辑地址到物理地址到映射】
在多道程序环境下,编译程序不可能预知编译后所得到的目标模块应存放在内存的何处,而应采用可重定位装入方式,它可以根据内存的具体情况装入模块装入到内存的适当位置。
值得注意的是, 在采用可重定位装入程序将装入模块装入内存后, 会使装入模块中的所有逻辑地址与实际装入内存的物理地址不同,图4-3示出了这一情况。(书P133)
例如,在用户程序的 1000 号单元处有一条指令LOAD 1,2500,该指令的功能是将 2500 单元中的整数 365 取至寄存器 1。但若将该用户程序装入到内存的 10000~15000号单元而不进行地址变换, 则在执行11000号单元中的指令时,它将仍从 2500 号单元中把数据取至寄存器1而导致数据错误。由图4-3 可见,正确的方法应该是将取数指令中的地址 2500 修改成 12500,即把指令中的相对地址 2500 与本程序在内存中的起始地址 10000 相加,才得到正确的物理地址12500。除了数据地址应修改外,指令地址也须做同样的修改,即将指令的相对地址 1000 与起始地址 10000 相加,得到绝对地址 11000。
通常,把在装入时对目标程序中指令和数据地址的修改过程称为重定位。【重定位:逻辑地址到物理地址到转换过程。】又因为地址变换通常是在进程装入时一次完成的,以后不再改变,故称为静态重定位。?【静态重定位:程序运行前进行地址映射。】
优点:无需硬件支持
缺点:a.程序重定位之后就不能在内存中搬动了;
???????????b.要求程序的存储空间是连续的,不能把程序放在若干个不连续的区域中。
3)动态运行时到装入方式
【运行时才装入需要的模块,装入后不进行地址映射,而是等到执行指令时才进行】
在具体对换功能的系统中,一个进程可能被多次换出,又多次被换入,每次换入后的位置通常是不同的。在这种情况下,就应采取动态运行时装入的方式。
动态运行时的装入程序在把装入程序装入内存后,并不立即把装入模块中的逻辑地址转换为物理地址,而是把这种地址转换推迟到程序真正要执行时才进行。为使地址转换不影响指令的执行速度,这种方式需要一个重定位寄存器的支持。
优点:a.目标模块装入内存时无需任何修改,因而装入之后再搬迁也不会影响其正确执行,这对于存储器紧缩、解决碎片问题是极其有利的;b.一个程序由若干个相对独立的目标模块组成时,每个目标模块各装入一个存储区域,这些存储区域可以不是顺序相邻的,只要各个模块有自己对应的定位寄存器就行。
缺点:需要硬件支持。
2.程序的链接
源程序经过编译后,可得到一组目标模块。链接🔗程序的功能是将这组目标模块以及它们所需要的库函数装配成一个完整的装入模块。在对目标模块进行链接时,根据进行链接的时间不同,可把链接分为如下三种:
1)静态链接方法
在程序运行之前,先将各目标模块及它们所需的库函数链接成一个完整的装配模块,以后不再拆开。把这种事先进行链接的方式称为静态链接方式。
我们通过一个例子来说明在实现静态链接时应解决的一些问题。在图 4-4(a)中示出了经过编译后所得到的三个目标模块A、B、C,它们的长度分别为 L、M和N。在模块A中有一条语句CALL B,用于调用模块B。在模块B中有一条语句CALL C,用于调用模块C。B和C都属于外部调用符号,在将这几个目标模块装配成一个装入模块时,须解决以下两个问题:
?(1)? 对相对地址进行修改。在由编译程序所产生的所有目标模块中,使用的都是相对地址,其起始地址都为 0,每个模块中的地址都是相对于起始地址计算的。在链接成一个装入模块后,原模块B和 C在装入模块的起始地址不再是 0,而分别是 L和 L+M,所以此时须修改模块B和C中的相对地址,即把原B中的所有相对地址都加上 L,把原 C中的所有相对地址都加上L+M。
(2)? 变换外部调用符号。将每个模块中所用的外部调用符号也都变换为相对地址,如把B 的起始地址变换为 L,把 C 的起始地址变换为 L+M,如图 4-4(b)所示。这种先进行链接所形成的一个完整的装入模块,又称为可执行文件。通常都不再拆开它,要运行时可直接将它装入内存。这种事先进行链接,以后不再拆开的链接方式,称为静态链接方式。
2)装入时动态链接
这是指将用户源程序编译后得到的一组目标模块,在装入内存时,采用边装入边链接的链接方式。即在装入一个目标模块时,若发生一个外部模块调用事件,将引起装入程序去找出相应的外部目标模块,并将它装入内存,并修改目标模块中的相对地址。
优点:a.便于修改和更新 b.便于实现目标模块的共享
3)运行时动态链接?
这种链接方式是,将对某些模块的链接推迟到程序执行时才进行。即,在执行过程中,当发生一个被调用模块尚未装入内存时,立即由OS去找到该模块,并将之装入内存,将其链接到调用者模块上。
3.逻辑地址与物理地址空间
逻辑地址:目标程序或可执行程序以“0”地址开始,形成的连续地址空间称为逻辑地址空间,其中地址称为逻辑地址。
逻辑地址的组成:是由一个段标识符加上一个指定段内相对地址的偏移量,表示为 [段标识符:段内偏移量]
物理地址:主存以字节为单位,且顺序编号,这种地址称为物理地址,对应的地址空间称为物理地址空间。
4.对换(Swapping)与覆盖(Overlay)
覆盖与对换技术是在多道程序环境下用来扩充内存的两种方法。
覆盖与对换可以解决在小的内存空间运行大作业的问题,是“扩充”内存容量和提高内存利用率的有效措施。
覆盖技术主要用在早期的 OS 中,对换技术则用在现代OS 中。
1)对换(Swapping)
所谓,“对换”,是指把内存中暂时不能运行的进程或者暂时不用的程序和数据换出到外存上,以便腾出足够的内存空间,再把已具备运行条件的进程或进程所需的程序和数据换入内存。
对换的类型:
a.整体对换 ?由于在中级调度中对换是以整个进程为单位的,故称之为“进程对换”或“整体对换”
b.页面(分段)对换
对换空间管理:
在具有对换功能的OS中,通常把磁盘空间分为文件区和对换区两个部分。
进程的换出与换入:
选择换出进程:首先选择处于阻塞状态或睡眠状态的进程,再选择其中优先级最低的进程作为换出进程。
选择换入进程:对换进程将定时执行换入操作,它首先查看PCB集合中所有进程的状态,从中找出“就绪”状态但已换出的进程。
2)覆盖(Overlay)
覆盖技术主要用在早期的 OS 中(内存 <64KB),可用的存储空间受限,某些大作业不能一次全部装入内存,产生了大作业与小内存的矛盾。
覆盖:把一个程序划分为一系列功能相对独立的程序段,让执行时不要求同时装入内存的程序段组成一组(称为覆盖段) ,共享主存的同一个区域,这种内存扩充技术就是覆盖。
5.重定位
通常,把在装入时对目标程序中指令和数据地址的修改过程称为重定位。
(2)连续内存分配方法,离散内存分配方法(分页、分段、段页)
1)连续内存分配方法
1.单一连续分配
在单道程序环境下,当时的存储器管理方式是把内存分为系统区和用户区两部分,系统区仅提供给OS使用,它通常是放在内存的低址部分。而用户区内存中,仅装有一道用户程序,即整个内存的用户空间由该程序独占。
缺点:只允许一个作业在内存中运行(只适用于单道系统),资源利用率不高
2.固定分区分配
划分分区的方法:
1*分区大小相等 ?缺点是缺乏灵活性,即当程序太小时,会造成内存空间浪费。
2*分区大小不等 增加存储器分配灵活性,应将存储器分区划分为若干个大小不等的分区。
特点:
①一个作业只能装入一个分区,当分区大小不能满足作业的要求时,该作业暂时不能装入。
②通过对“分区使用表”的改写,来实现主存的分配与回收。作业在执行时,不会改变存储区域,所以采用静态地址重定位方式。此方法易于实现,系统开销小。
③有内部碎片。分区总数固定,限制了并发执行的作业数目。
3.动态分区分配
动态分区分配又称为可变分区分配,它根据进程的实际需求,动态地为之分配内存空间。
1*动态分区分配中的数据结构
①空闲分区表,在系统中设置一张空闲分区表,用于记录每个空闲分区的情况。每个空闲分区占一个表目,表目中包括分区号、分区大小和分区始址等数据项,如图4-6所示。
②空闲分区链,为了实现对空闲分区的分配和链接,在每个分区的起始部分设置一些用于控制分区分配的信息,以及用于链接各分区所用的前向指针,在分区尾部则设置一后向指针。通过前、后向链接指针,可将所有的空闲分区链接成一个双向链,如图4-7所示。
? ??
2*动态分区分配算法?
4.动态可重定位分区分配
与动态分区分配基本相同,增加了拼接功能,在程序运行时进行动态重定位。
1*紧凑 ?通过一点内存中作业的位置,把原来多个分散的小分区拼接成一个大分区的方法,称为“拼接”或者“紧凑”。
2*动态重定位 ?为使地址的转换不会影响到指令的执行速度,必须有硬件地址变换机构的支持,即必须在系统中增设一个重定位寄存器,用它来存放程序(数据)在内存中的起始地址。程序在执行时,真正访问的内存地址是相对地址与重定位寄存器中的地址相加而形成的。
3*动态重定位分区分配算法 ?与动态分区分配算法基本一致,差别在于:增加了紧凑功能。
2)离散内存分配方法
1.分页存储管理方式
a.将用户程序的地址空间分成若干个固定大小的区域,称为“页”或者“页面”。同时也将内存空间分为 若干个物理块或页框,页和块的大小相同,这样可将用户程序的任一页放入任一物理块中,实现了离散分配。
【注】由于进程的最后一页经常装不满一块,而形成了不可利用的碎片,称之为“内部碎片”。
b.分页地址中的地址结构如下:
31 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 12 | 11 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0 | 页号P | 位移量W |
若给定一个逻辑地址空间的地址为 A,页面的大小为L,则页号P和页内地址d计算公式如下:
? , ????
其中,INT是整除函数,MOD是取余函数。
即?逻辑地址?页面大小的整数部分为页号P,余数为页内地址d。
c.页表/页面映像表
记录了相应页在内存中对应的物理块号。
页表的作用是实现从页号到物理块号的地址映射。
a.基本的地址变换机构
该机构的基本任务是实现从逻辑地址到物理地址的转换。由于页内地址和物理地址是一一对应的,因此,地址变换机构的任务实际上只是将逻辑地址转中的页号转换为内存中的物理块号。
页号大于页表长度:表示本次访问的地址已超越进程的地址空间,这一错误将被系统发现,并产生一地址越界错误
页号在页表长度内:物理地址=块号*页长+页内地址,
表项在页表内法位置(地址)=页表始址 + 页号*页表项长度?
?b.具有块表的地址变换机构
在地址变换机构中增设一个具有并行查寻能力的特殊高速缓冲寄存器(类似于cache),称为“联想寄存器”或“快表”,用以存放当前访问的那些页表项。?
a.在基本分页存储管理中,
b.在引入快表的分页存储管理中,
其中,a为命中率,t表示访问一次内存所需时间,?表示查找快表所需时间。
【命中率,是指使用快表并在其中成功查找到所需页面的表项的比率。】
2.分段存储管理方式
引入分段存储管理方式的目的主要是为了满足用户/程序员在编程和使用上多方面的要求。
1*方便编程 ? ?2*信息共享 ? ?3*信息保护 ? ?4*动态增长 ? ?5*动态链接
1*地址空间分段
(1)段可独立编写和编译
(2)段可以不等长
(3)每段可以获得一个段号且无次序要求
2*段表
段表是用于实现从逻辑段到物理内存区的映射。
(1)记录段在内存中的基址(该段在内存中的起始地址)和段的长度
(2)每个进程一张段表
(3)每段占一个表项
3*地址变换机构
物理地址=基址d+段内地址
段项在段表中的位置=段表始址+段号*段表长度
?
4*分页和分段的比较
(1)页大小固定,段大小不固定。
(2)分页的地址空间是一维的,分段是二维的。
(3)分页是为了方便管理,分段是为了满足用户需求。
(4)分页对用户透明,分段是用户可见的。
3.段页式存储管理方式
(1)存储空间等分为块
(2)地址空间分段,段内分页
(3)作业运行前,所有段的所有页面投入内存
段页式地址结构:
在段页式系统中,为了获取一条指令或数据,须三次访问内存。
在地址变换机构中增设一个高速缓冲寄存器,每次访问它,都必须同时利用段号和页号取检索高速缓存,若找到匹配的表项,便可从中得到相应的物理块号,用来于页内地址一起形成物理地址;若未找到匹配表项,则仍需第三次访问内存。
|