学习笔记——OS存储器管理

一、存储器的层次结构

处理机与存储器速度肯定无法达到匹配,因此,引入多层次结构的存储器系统。

速度:从上到下依次降低;容量:从上到下依次增大。

主存:存放指令和数据;主存访问速度远远低于CPU执行速度。

寄存器:与处理机有相同的速度,但价格昂贵。

高速缓存:介于寄存器和存储器之间,主要用于存放常用的数据,以减少处理机对内存的访问次数,提高执行速度。将哪些数据放入,涉及到程序的局部性原理,即在一较短时间内,程序的执行仅局限于某个部分。

磁盘缓存:并不是实际存在的,利用主存中的部分存储空间存放从磁盘读出(或写入)的信息,是辅存的高速缓存。

二、程序的装入和链接

用户程序要在系统中执行,必须装入内存:

(1)编译:由编译程序进行编译,形成若干个目标模块;

(2)链接:由链接程序将目标模块及所需的库链接在一起,形成一个完整的装入模块;

(3)装入:由装入程序将装入模块装入内存。

装入

1)绝对装入方式:计算机系统很小,且仅运行单道程序,将逻辑地址直接用做物理地址。

2)可重定位装入方式:将逻辑地址(从0开始)映射为物理地址。把在装入时对目标程序中指令和数据地址的修改过程称为重定位。又因地址转换在程序装入时一次完成,以后不再改变,因此称为静态重定位。

3)动态运行时的装入方式:允许装入内存的任何位置,但不能在程序运行时移动。把装入模块装入内存,并不立即把装入模块中的逻辑地址转换成物理地址,而是把这种地址转换推迟到程序真正执行时才进行。因此装入内存后的所有地址仍是逻辑地址。

链接

将目标模块以及用到的库函数链接成一个完整的装入模块。

(1)静态链接方式:程序运行前做好所有准备,将所有目标模块及库函数链接成一个完整的装入模块,以后不再拆开。称为静态链接方式。需要进行相对地址修改。

(2)装入时动态链接:得到目标模块后,装入内存时,采用边装入边链接方式。即在装入一个目标模块时,若发生外部调用事件,将引入装入程序去找到相应的外部目标模块,并将它装入内存。便于修改和更新,相对于静态链接方式,可以进行打开重装。便于实现对目标模块的共享。

(3)运行时动态链接:将对某些模块的链接推迟到程序执行时才进行。需要什么模块由OS将之调入内存,并进行链接。

三、交换

       基本思想:把内存中暂时不能运行的进程或暂时不用的程序和数据换到外存上,以便腾出足够的内存空间,再把已具备运行条件的进程或进程所需的程序和数据换入内存。可以提高处理机的利用率和系统吞吐量。

       注意问题:

       1)为了有效使用CPU,需要每个进程的执行时间比交换时间长;

       2)换出进程时,需要保证该进程完全处于空闲状态;

       3)交换通常在有许多进程运行且内存空间吃紧时开始启动。

四、连续分配存储管理方式

连续分配方式是指为一个用户分配一个连续的内存空间。分为以下三种。

1.单一连续分配

       系统区给OS使用,一般在低地址部分;用户区给用户使用。只能用于单用户、单任务OS中。

2.固定分区分配

       为了能在内存中装入多道程序,且这些程序之间又不会发生相互干扰,于是将整个用户空间划分为若干个固定大小的区域,在每个分区中只装入一道作业,则保证可运行多道程序。下面两种分区方式:

(1)分区大小相等:所有的内存分区都相等。缺乏灵活性。

(2)分区大小不等:将内存划分为若干个大小不等的分区。根据程序的大小,为之分配适当的分区。

         为了便于内存分配,通常将分区按其大小进行排队,建立一张分区使用表。

            

3.动态分区分配

(1)相关数据结构

用以描述空闲分区和已分配分区的情况。通常有两种:空闲分区表和空闲分区链。

空闲分区表:

空闲分区链:

(2)分区分配操作

主要操作是分配内存和回收内存。

分配内存:按照某种分配算法,从空闲分区表(链)中找到所需大小的分区。

回收内存:进程运行完毕,释放内存,系统根据回收区的首址,从空闲区表(链)中找到相应的插入点。

(3)动态分区分配算法

为了把一个新作业装入内存,必须按照一定的分配算法,从空闲分区表(链)中找到一合适分区分配给该作业。

1)基于顺序搜索的分配算法

       首次适应(first fit,FF)算法:要求空闲分区链以地址递增的次序链接。分配时,顺序查找,直到找到一个满足大小的分区为止。优先倾向于低地址的空闲分区,则造成低地址碎片较多;每次从低地址开始查找,增加开销。

       循环首次适应(next fit,NF)算法:为了解决FF算法的缺点,不再从链首查找,而是从上次找到的空闲分区的下一个空闲分区开始查找。

       最佳适应(best fit,BF)算法:每次为作业分配内存时,总是把能满足要求、又是最小的空闲分区分配给作业,避免“大材小用”。要求将所有的空闲分区按其容量从小到大的顺序排列。但从宏观上看,算法未必最佳,因为每次切下来的碎片也最小,难以利用。

       最坏适应(worst fit,WF)算法:与最佳适应相反,总是选择最大的空闲区。使剩下的碎片不至于太小,可利用。要求空闲分区按从大到小的顺序排列。查找时,只看第一个分区能否满足即可。

2)基于索引搜索的分配算法

       快速适应(quick fit)算法:将空闲分区根据其容量大小进行分类,对每一类具有相同容量的所有空闲分区,单独设立一个空闲分区表。同时,在内存中设立一张管理索引表,每一个索引表项对应一种空闲分区类型。

       伙伴系统(buddy system):该算法规定,所有的分区均表示为2^{k}。当要求分配长度为n的存储空间时,首先计算一个i值,使2^{i-1}\leq n\leq 2^{i},然后在空闲分区大小为2^{i}的空闲分区链表中查找。找到则分配;找不到,则在2^{i+1}中查找,找到了则分割为两个分区,一个进行分配,另一个插入的空闲分区链表。依次如此执行。

       在伙伴系统中,其分配和回收的时间性能取决于空闲分区的位置和分割、合并空闲分区所花费的时间。采用索引搜索算法,比顺序搜索算法好;回收分区时,要进行分区合并,则比快速适应算法差。

       哈希算法:利用哈希快速查找,以及空闲分区的分布规律,建立哈希函数,构造哈希表。

4.动态可重定位分区分配

(1)紧凑

       一台计算机运行时间长了后,内存被分割成许多小的分区,而缺乏大的空闲时间,如下左图。若某作业要求获得40KB的内存空间,由于必须分配连续的地址空间,故此作业无法装入。一种方法是:将内存中的作业移动,使它们相互邻接,则小的空闲分区拼接成一个大的空闲分区,称为“紧凑”,如下右图。

       每一次紧凑后,都必须对移动了的程序或数据进行重定位,大大影响到系统的效率。故用下面的动态重定位。

(2)动态重定位

       即前面所介绍的动态运行时装入的方式,装入内存后的所有地址仍是逻辑地址,将逻辑地址转换为物理地址推迟到程序指令真正执行时进行。重定位寄存器中存放程序(数据)在内存中的起始地址。程序执行时,真正访问的内存地址是相对地址与重定位寄存器中的地址相加而成的。地址变换过程是在程序执行期间,随着对每条指令或数据的访问自动进行的,故称为动态重定位。当系统进行紧凑后,程序(即逻辑地址)不必改变,只需改变重定位寄存器中的值。

(3)动态重定位分区分配算法

       除了增加了紧凑功能,其它与动态分区算法一样。

五、非连续分配管理方式

若允许将一个进程直接分散地装入许多不相邻接的分区中,便可充分利用内存空间,而无需进行“紧凑”。

根据离散分配时所分配地址空间的基本单位不同,又可将离散分配分为三种:

(1)分页存储管理方式:将用户程序分为若干固定大小的区域,也将内存空间分为若干物理块,页和块大小相同,从而将用户程序的任一页放入任一物理块。

(2)分段存储管理方式:为了满足用户要求而形成的一种存储管理方式。把用户程序的地址空间分为若干大小不同的段,在存储分配时,以段为单位。

(3)段页式存储管理方式:分页和分段两种方式结合的产物。

1.分页存储管理方式

(1)页表

将进程的各个页离散地存储在内存中的任一物理块中,为保证进程的各个页能找到对应的物理块,系统要建立一张页表。页表的作用是实现从页号到物理块号的地址映射。

(2)基本原理

将进程逻辑地址空间分为若干个页,并为各页加编号,地址结构如下,分为页号和页内地址;相应地,将内存的物理空间分为若干个块。

为了能将用户地址空间中的逻辑地址转换为内存空间中的物理地址,在系统中必须设置地址转换机构,即页表。

地址变换过程:当进程要访问某个逻辑地址的数据时,分页地址变换机构自动地将有效地址分为页号和页内地址两部分,再以页号为索引去检索页表;页表起始地址与页号相加,找到块号;将块号与页内地址拼接成物理地址,即完成地址转换。

(3)块表TLB

页表和访问的数据都存在内存中,因此CPU每存取一个数据需要两次访问内存。第一次是访问内存中的页表,找到物理块号,将块号与页内偏移量相拼接,形成物理地址;第二次是根据物理地址访问内存中所需的数据。计算机处理速度降低1/2。

为了提高地址变换速度,可设置一个高速缓冲寄存器,TLB(快表,Translation Look aside Buffer,联想寄存器,Associative Memory)。

地址变换过程:CPU给出有效地址后,由地址变换机构将页号送入TLB,直接读出物理块号,与页内地址相拼接形成物理地址,访问内存中的数据,只需一次访存;若TLB中找不到,则再找页表。

2.分段存储管理方式

(1)引入

为了满足用户在编程和使用上多方面的要求。很实用,许多高级语言及C语言的编译程序都支持分段存储管理方式。

1)方便编程:用户把自己的作业按照逻辑关系分为若干个段,每个段从0开始编址,有自己的名字和长度。

2)信息共享:在实现对程序和数据的共享时,是以信息的逻辑单位为基础的,如函数、过程及文件。而页只是存放信息的物理单位(块),并无完整的逻辑意义,一个过程通常包含若干个页面,难于分享。

3)信息保护:信息保护通常也是以信息的逻辑单位为基础的,如一个过程、函数或文件。

4)动态增长:数据段通常动态增长,难于采取预先分配的策略。

5)动态链接:并不是把所有程序都调入内存才开始执行,而是需要时再入,也是以目标程序(段)作为链接的基本单位。

(2)段表

为每个分段分配一个连续的分区,进程中的各个段离散地装入内存中的不同分区中。为保证程序正常执行,必须能从物理内存中找出每个逻辑段所对应的位置,即建立段表。段表放在内存中,用于实现从逻辑段到物理内存区的映射。

(3)基本原理

作业的地址空间被分为若干个段,每个段定义了一组逻辑信息,如主程序段、子程序段及数据段等。其逻辑地址由段号(段名)和段内地址组成。

为了实现从逻辑地址到物理地址的变换功能,系统中设置段表。

同页式存储管理方式,需要访问两次内存,第一次访问段表找基址,第二次根据基址找物理地址中的数据。

地址变换过程:将段号与段表起始地址相加得到该段对应段表项的位置,读出该段在内存中的起始地址。再将该段的基址与段内地址相加,即得到要访问内存的物理地址。

(4)分页和分段的主要区别

相同点:

都采用离散分配方式,且都通过地址映射机构实现地址变换。

不同点:

1) 页是信息的物理单位,分页是系统管理上的需要;段是信息的逻辑单位,分段是更好满足用户的需要。

2)页的大小固定且由系统决定;段的长度不固定,决定于用户所编写的程序。

3)分页的用户程序地址空间是一维的,是系统的行为,程序员只需一个符号即可表示一个地址;分段的地址空间是二维的,是用户的行为,程序员既需给出段名,又需给出段内地址。

3.段页式存储管理方式

对分页和分段“各取所长”,即有分段的便于实现、分段可共享、易于保护、可动态链接等优点,又像分页系统那样解决内存的外部碎片问题。

(1)引入

将用户程序分为若干个段,再把每个段分为若干个页。如下该作业有三个段:主程序段、子程序段和数据段。地址结构由段号、段内页号和页内地址三部分组成。

利用段表和页表实现从用户地址空间到物理(内存)空间的映射。

(2)基本原理

地址变换过程:利用段号和段表起始地址求出该段对应的段表项在段表中的位置,从中得到该段的页表始址;利用逻辑地址中的段内页号获得相应的页表项位置,从中读出该页所在的物理块号;再利用块号和页内地址来构成物理地址。

为了获得一条指令或数据,须三次访存。第一次访问内存中的段表,取得页表始址;第二次访问内存中的页表,取得物理块号,与页内地址形成物理地址;第三次访问内存,取得指令或数据。显然,严重影响执行速度,在地址变换机构中设置高速缓冲寄存器。每次访问它时,同时利用段号和页号去检索高速缓存,找到物理块号,则仅需一次访存;若找不到再三次访存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值