操作系统-存储器管理部分(待更新)

存储器历来都是计算机系统中重要的组成部分。仍然是一种宝贵而又稀缺的资源。

如何对它加以有效的管理,不仅直接影响到存储器的利用效率,而且会影响系统的性能。

存储器的管理的主要对象是内存。在计算机执行时,几乎每一条指令都会涉及到对存储器的访问。

存储器的三个理想条件(这三个条件从现在技术来讲是不可能同时达到的

1.对存储器的访问速度要跟得上处理机的运行速度。

2.要求存储器要有很大的容量。

3.而且存储器的造价应该很低。

在现代计算机系统当中无一例外的采用了多层结构的存储器系统

 

存储器的多层结构

对于通用计算机而言,存储层次至少应具有三级:CPU寄存器,主存,辅存

在存储层次当中,层次越高,存储介质的访问速度越快,价格越高,其存储容量越小。

寄存器,高速缓存,主存储器,磁盘缓存均属于操作系统中存储管理的管辖范畴。断电后它们所保存的信息将会消失。

固定磁盘,可移动存储介质的管理属于设备管理的范畴,它们存储的信息将被长期保存。

 

可执行存储器

在计算机系统的存储层次当中,寄存器和主存储器又被称为可执行存储器。

进程可以在很少的时钟时期内使用一条load或store指令对可执行存储器进行访问。而对辅存的访问则需要通过I/O设备来实现,所消耗的时间远大于访问可执行存储器所消耗的时间,一般相差3个数量级或者更多。

操作系统的存储管理负责对可执行存储器的分配,回收以及各存储层次之间的数据交换进行管理。

 

主存储器

主存储器简称内存或者主存,是计算机的主要部件,用于保存进程运行过程中的程序与数据,也称为可执行存储器。通常,处理机都是从主存储器中获取指令和数据的。

由于主存储器访问速度远低于CPU执行指令的速度,为缓解此矛盾,在计算机系统当中引入了寄存器和高速缓存。

 

寄存器

寄存器具有和处理机相同的速度,故对寄存器的访问速度最快,完全能与CPU协调工作,但价格十分昂贵,于是存储容量不能很大。

在当前的微机系统与大中型机当中,寄存器的位数通常为32与64位,而在小型的嵌入式计算机中,寄存器的位数通常为8位。

 

高速缓存

高速缓存是现代计算机结构中的一个重要部件,它是介于寄存器与存储器之间的存储器,主要用于备份主存中较常用的数据,以减少处理机对主存储器的访问次数,这样可以大幅度提高程序的运行速度。

高数缓存的容量大于寄存器的容量,访问速度比主存储器快。

在计算机系统中,为了缓解内存与处理机速度之间的矛盾,许多地方都设置了高速缓存。

通常,进程的数据和程序存放在主存储器当中,仅当要被访问时,才被临时复制到高速缓存当中。当CPU访问一组特定信息的时候,首先会检查该信息是否在高速缓存当中,如果在,则直接从高速缓存中取出,不需要去访问主存。否则,需要访问主存来获取信息。

紧靠内存的一级高速缓存的速度最高,容量最小。越远,速度越低,容量越大。

 

磁盘缓存

由于目前磁盘的I/O速度远低于对主存的访问速度,为了缓解两者速度的矛盾,设置了磁盘缓存,主要用于暂时存放频繁使用的一部分磁盘数据和信息,以减少访问磁盘的次数。

数据必须先存在主存当中,才能输出到辅存当中。

 

程序的装入和链接

用户程序变成一个可以执行的程序通常要经过以下几个步骤:

1.编译,由编译程序对源程序进行编译,形成若干个目标模块。

2.链接,由链接程序将编译程序形成后的一组目标模块以及它们所需要的库函数链接在一起,形成一个完整的装入模块。

3.装入,由装入程序将装入模块装入内存。

在将一个装入模块装入内存时,可以有如下三种装入方式:

1.绝对装入方式

当计算机系统很小,且仅能运行单道程序的时候,完全有可能知道程序将驻留在内存的什么位置。此时可以采用绝对装入方式。

用户程序经过编译后,将产生绝对地址的目标代码。装入模块被装入内存之后,由于程序和数据的逻辑地址与物理地址是相同的,所以不需要改变程序和数据的地址。

 

可重定位装入方式(在装入内存时完成的,装入完成后全部的地址都是物理地址)

它可以根据内存的具体情况将装入模块装入到内存的合适位置。

在多道程序环境下,编译程序不可能知道经过编译后的目标模块应存放在内存的什么位置。因此,对于用户程序编译所形成的若干个目标模块,它们的起始地址通常都是从0开始,程序中的其他地址都是相对于起始地址计算的。

通常,把装入进程时对目标进程的指令和数据的地址的修改过程叫做重定位。又因地址变换通常是在进程装入时一次完成的,此后不再发生变化,因此叫做静态重定位。

可重定位装入方式可以将装入模块加载到内存的任何允许的位置,可用于多道程序环境。

 

动态运行时的装入方式

动态运行时的装入程序在把装入模块装入内存时,并不立即把模块的逻辑地址变为物理地址,而是当该程序真正要执行时才进行地址转换,因此装入内存后的所有地址均为逻辑地址。

 

程序的链接

在对目标模块进行链接时,根据进行链接的时间不同,可把链接分为三种:

1.静态链接方式

在程序运行前,先将目标模块和所需的库函数链接成为一个装入模块,以后不再拆开。我们把这种事先进行链接的方式叫做静态链接方式。

2.装入时动态链接

这是指将用户源程序经过编译后生成的一组目标模块,不先将它们链接起来,而是采用边装入内存边链接的方式。装入时动态链接有两个优点:便于修改和更新,便于实现对目标模块的共享。

3.运行时动态链接

在许多情况下,应用程序在运行时,每次要运行的模块可能是不同的。

将某些模块的链接推迟到程序真正要执行时再进行。亦即,在执行过程中,当发现一个被调用模块尚未装入内存中时,立即由OS去找到该模块,并将之装入内存,将其链接到调用者模块上。

凡是在执行过程中未被用到的目标模块,都不会被装入内存和链接到装入模块上,大大提高了程序的装入过程的速度,而且可以节省大量的内存空间。

 

连续分配存储管理方式

连续分配方式可分为四类:单一连续分配,固定分区分配,动态分区分配,以及冬天可重定位分区分配算法四种方式。

单一连续分配

在单道程序环境下,当时存储器管理方式是把内存分为内存区和系统区两部分,系统区仅提供给OS使用,它通常是放在内存的低地址当中。而用户区因为是单道程序环境,仅能装有一道程序,于是整个用户区都是属于该程序的,这种存储器分配方式为单一连续分配方式。

固定分区分配

为了能在内存中装入多道程序,且使这些程序之间不会相互干扰,于是将用户区空间划分为若干个固定大小的区域,分别在每个分区中装入一道作业,这样就形成了最早的,最简单的可运行多道程序的分区式存储管理方式。

动态分区分配

动态分区分配又称为可变分区分配,它是根据进程的实际需要,动态的为之分配内存空间。

 

基于顺序搜索的动态分区分配算法

为了实现动态分区分配,通常将空闲分区链接成为一个链,所谓顺序搜索,是依次搜索空闲分区链上的空闲分区,直到找到满足大小需求的空闲分区为止。基于顺序搜索的动态分区分配算法有如下四种:首次适应算法,循环首次适应算法,最佳适应算法,最坏适应算法。

首次适应算法

在分配内存时,从链首开始查找,直到找到一个大小符合要求的空闲分区为止。然后再按照请求大小,从符合要求的空闲分区中划出请求大小的分区,余下的空闲部分仍在空闲分区链当中。

该算法倾向于优先利用低地址的空闲分区,从而保留高地址的大空闲区。从而为大作业的分配创建了条件。

缺点是优先利用低地址的空闲分区,会对低地址进行不断的划分,导致产生许多不能利用而且很小的“碎片”,并且查找是从低地址开始查找的,从而会导致增大查找可利用空闲分区的开销。

循环首次适应算法

目的:为减小空闲分区的碎片化程度,以及减小查找可利用空闲分区的开销。

在为进程分配内存空间时,不再从链首进行查找,而是从上一次查找的空闲分区的下一个空闲分区进行查找。

优缺点:这样会使内存中的空闲分区分配的更加均匀,从而减小了碎片化和开销,但是减少了大分区。

最佳适应算法

将空闲分区按照分分区容量由小到大进行排序链接形成一条链,当查找到第一个满足要求的空闲分区时,该分区肯定是最佳的。

每次分配后所切割下来的剩余部分总是最小的,于是会留下许多难以利用的碎片。

最坏适应算法

将空闲分区按照分区容量由大到小进行排序链接成一条链,我们只需要查找第一个空闲分区,于是该算法的查找效率很高。

 

基于索引搜索的动态分区分配算法

基于顺序搜索的动态分区分配算法比较适用于不太大的系统,当系统很大时,内存分区可能会很多,相应的空闲分区链也会很长,这时采用顺序搜索分区的方式就会很慢。

在大,中型系统当中,往往会采用基于索引搜索的动态分区分配算法,目前常用的有快速适应算法,伙伴系统和哈希算法。

快速适应算法

该算法又称为分类搜索法,是将空闲分区根据容量大小进行分类,对于每一类具有相同容量的所有空闲分区,单独设立一个空闲分区链表,这样系统当中存在多个空闲分区链表。同时,在内存中设立一张管理索引表,其中的每一个索引表项对应了一种空闲分区类型,并记录了该类型空闲分区链表表头的指针。

空闲分区的分类是根据进程常用的空间大小进行划分的。

该算法在搜索可分配的空闲分区时分为两步:第一步是根据进程的长度,从索引表中寻找能容纳它的最小空闲分区链表。第二步是从该空闲分区链表中把第一块取下来即可。

该算法在进行空闲分区分配时,不会产生任何分区分割,所以能保留大的分区,满足对大空间的需求,也不会产生碎片,查找效率高。

 

动态可重定位分区分配

紧凑

若把大作业装入,可采用的一种方式为:将内存中的所有作业进行移动,使它们全都相邻接。这样,即可把原来分散的多个空闲小分区拼接成一个大分区,从而来分配给大作业。这种通过移动内存中的作业位置,把原来多个分散的小分区拼接成一个大分区的方法,称为“紧凑”。

程序装入内存的实际地址=相对地址+重定位寄存器的地址

动态重定位分区分配算法

该算法与动态分区分配算法基本相同,差别仅在于该算法引入了“紧凑”,通常,当该算法不能找到一个足够大的内存空间来满足用户的需求时,如果所有小的空闲分区的容量和大于用户所需求,则进行紧凑操作,把小分区合并为大分区,分配给用户程序,否则,返回分配失败信息。

 

对换

对换技术也叫交换技术。

所谓“对换”,是指把内存中暂时不能运行的进程或者暂时用不到的程序或数据换出到外存当中,将已具备运行条件的进程或者进程所需要的程序和数据换入到内存当中。直接提高了处理机的利用率和系统吞吐量。

对换的类型

在每次对换的时候,都是将一定数量的程序或数据换入或换出内存。根据对换时的对换的数量,可将对换分为以下两类:

1.整体对换

 处理机中级调度相当于存储器的对换功能,目的是用来解决内存紧张问题,并可进一步提高资源的利用率和系统的吞吐量。

2页面对换

如果对换是以进程的一个“页面”或“分段”为单位进行的,则分别称之为“页面对换”与“分段对换”。这种对换方式是实现请求分页与请求分段式存储管理的基础,其目的是为了支持虚拟存储系统

 

对换空间的管理

在具有对换功能的OS当中,通常把磁盘空间分为文件区与对换区。

对文件区管理的主要目标

文件区占用磁盘空间的大部分,用于存储各类文件,由于通常的文件都是较长时间驻留在外存上,对它的访问频率较低,故对文件区管理的主要目标是提高文件存储空间的利用率,加快对文件的访问速度。

对对换空间管理的主要目标

对换空间只占用磁盘空间的一小部分,用于存放从内存中换出的进程。

对对换空间管理的主要目标:

1.提高进程的换入换出速度

2.然后才是提高文件存储空间的利用率

 

进程的换出与换入

进程的换出

对换进程在实现进程换出时,将内存中的进程换出到对换区,腾出内存空间。

进程的换入

对换进程将定时进行换入操作,它首先去查看PCB集合当中所有进程的状态,从中找出处于“就绪”状态但已换出的进程,若存在多个这样的进程,它将选择其中已换出到磁盘上时间最久的进程,为其申请内存空间,若申请成功,则直接从外存调入内存,若内存空间不足,则先换出部分进程,腾出足够的内存空间,再将该进程调入内存当中。

由于要交换一个进程需要很多时间,所以说对于提高处理机的利用效率而言,它并不是一个很有效的办法。目前用的较多的方案是,在处理机正常运行时,并不启动对换进程。当发现许多进程在运行时经常发生缺页或者内存紧张的情况,则运行对换进程,将一部分进程调到外存当中。

 

分页存储管理方式

连续分配方式会产生很多碎片,虽然可以通过“紧凑”的方法将许多碎片拼接为可用的大分区,但须为之付出很大的开销 。

根据离散分配时分配地址空间的基本单位不同,可分为以下三种离散分配方式:分段存储管理方式,分页存储管理方式,段页存储管理方式。

分页存储管理方式

在该方式中,将用户程序的地址空间划分为若干个固定大小的区域,称为“页”或“页面”。典型的页面大小为1kb。相应地,也将内存空间分为若干个物理块或页框,页和块大小相同。

分段存储管理方式

在该方式中,将用户程序的地址空间划分为不同大小的段,每段拥有一组相对完整的信息,在存储器分配时,以段为单位,这些段在内存中可以不相邻,于是是离散分配。

段页存储管理方式

分页存储管理与分段存储管理两者相结合的产物,现今应用较为广泛。

 

页面

分页存储管理将进程的逻辑地址空间划分为若干个页,并为每一页设上编号,把内存中的物理地址空间划分为若干个块,并为他们加以编号。

在为进程分配内存的时候,以块为单位,将进程中的若干页分别装入到可以不相邻接的物理块当中。

页面大小

在分页系统中,若选择过小的页面大小,虽然可以减小内存碎片,有利于内存利用率的提高,但另一方面会造成每个进程占用较多的页面,导致进程的页表过长,占用大量内存。

若选择过大的页面大小,虽然可以提高进程换入换出的速度,但碎片化会加重。

页表

在分页系统中,允许将进程个各个页离散的存储在内存中的任意物理块当中,为保证进程能够正确的运行,即能在内存中找到每个页所对应的物理块,系统又为每个进程创建了一张页面映像表,即页表。

在进程地址空间内的所有页,均在页表中有一个页表项,其中记录了该页所对应的内存中物理块的编号。在配置了页表后,进程执行时,通过查找该页表,就可知道页所对应的物理块的编号。

页表的作用是实现了从页号到物理块号的地址映射。

 

地址变换机构

为了实现将用户地址空间的逻辑地址转换为内存地址空间的物理地址,系统中必须有地址变换机构。

地址变换机构的基本任务是将逻辑地址转换为内存中的物理地址,由于页内地址和物理地址是一一对应的。因此,地址变换机构的任务实际上只是将逻辑地址的页号转换为内存地址中的物理块号。由于该功能由页表可以实现,因此地址变换任务是借助页表来完成的。

 

基本的地址变换机构

页表功能是由一组专门的寄存器实现的,每一个页表项使用一个寄存器,由于寄存器有较高的访问速度,可以提高地址变换的速度,但寄存器的成本太高,于是页表大多驻留在内存当中。

在系统中只设置一个页表寄存器(PTR),用于存放页表的起始地址和页表的长度。(当进程未被调度时,进程的页表起始地址与页表长度存放在进程的PCB块当中,当进程被调度程序调度的时候,才会将这两个数据放入页表寄存器当中)。

如果页号大于等于页表长度,则说明本次访问的地址超过了进程的地址空间,操作系统会产生一次越界中断。

 

具有快表的地址变换机构

由于页表是存放在内存当中的,每次CPU存取一个数据的时候,都要经过两次访问内存的操作。

1.第一次访问内存,访问内存中的页表,找到指定页的物理块号,再将块号与页内偏移量拼接,形成物理地址。

2.第二次访问内存,才是真正的获取第一次所得地址中的所需数据。

为了提高地址变换速度,可在地址变换机构中增设一个具有并行查寻能力的特殊高速缓冲寄存器,又称“联想寄存器”,或称为“快表”,用于存放当前访问的那些页表项。

具有高速缓冲寄存器的地址变化机构的地址变换过程

在CPU给出有效地址之后,由地址变换机构自动的把页号P送入高速缓冲寄存器当中,并将该页号与高速缓冲寄存器中的页号进行匹配,如果匹配成功,说明该页表项存在于快表当中,于是可直接从快表中读出该页所对应的物理块号,并将其放入物理地址寄存器当中。

 

访问内存的有效时间

从进程发出指定逻辑地址的访问请求,经过地址变换,到在内存中找到对应的物理地址单元并从中读取完数据所花费的总时间叫做内存的有效访问时间。

在近两年推出的64位OS中,把可直接寻址的存储器空间减少为45位长度左右,这样便于用三级分页结构进行分页存储管理。

反置页表

反置页表是为每一个物理块设置一个页表项,并将它们按照物理块号进行排序,其中的内容是页号和所属进程的标识符。

在利用反置页表进行地址变换时,是根据进程标识符和页号,去检索反置页表,如果检索到与之匹配的页表项,则该页表项的序号i就是该页所在的物理块号,可用该物理块号和页内地址相拼接形成物理地址,送入物理地址寄存器。

反置页表可有效减少页表所占用的内存空间。

 

分段存储管理方式

推动分页存储管理方式的目的是提高内存空间的利用率。

分段存储管理的目的是满足用户在编程和使用上的多种需求。

通常,用户把自己的作业按照逻辑关系划分为若干个段,每个段起始地址都从0开始,并有自己的名字和长度。逻辑地址=段内地址+段号。

信息保护是以信息的逻辑单位为基础的,而且经常是以一个过程,函数或者文件为基本单位进行保护的。例如我们如果希望函数A只允许进程执行,而不允许读写,则只需要将函数A所在的段标上只执行的标志即可。

而在分页存储管理中,函数A可能要占用若干个页面,而且其中的第一个和最后一个页面还装有其他程序段的数据,它们可能有着不同的保护属性,这样就很难对这些页面实施统一的保护。

分段存储管理能更有效更方便的实现对信息的保护。

分段存储管理非常适合动态链接。

 

分段系统的基本原理

在分段存储管理方式中,作业的地址空间被分为若干个段,每个段定义了一组逻辑信息。每个段都有自己的段号(段名)与段长度。

每个段都从0开始编址,并采用一段连续的地址空间。段的长度由相应的逻辑信息组的长度决定。

段表

段表实现了从逻辑段到物理内存区的映射。

可重入代码又称为“纯代码”,是一种允许多个进程同时访问的代码。为了保证各个进程执行的代码完全相同,绝不允许在执行过程中可重入代码发生改变。可重入代码是一种不允许任何进程对它进行修改。

 

段页式存储管理方式

段页式系统的基本原理是分段和分页原理的结合,现将用户程序分为若干个段,再将若干个段分为若干个页,并为每一个段赋予一个段名。

在段页式系统当中,其地址结构由段号,段内页号,页内地址组成。

段表的内容与分段系统略有不同,它不再是内存始址和段长,而是页表长度和页表始址。

 

posted @ 2019-11-27 00:04  ReVe1Se  阅读(582)  评论(0编辑  收藏  举报