tags: 操做系统, title: 操做系统第六篇【存储器管理】程序员
首先,通常的存储器咱们就会认为它包含着三部分:算法
所以,咱们的存储器每每是使用三层结构的。编程
在操做系统的角度而言,咱们面对存储器就是面对程序的装入和链接安全
通常地**,用户程序向要在系统上运行,就要经历下面几个步骤:**数据结构
用户程序中使用的地址称为相对地址或逻辑地址或虚拟地址。 在早期,当程序装入内存时,指令存储在内存中的物理地址与其逻辑地址彻底相同. 这种程序的装入方式称为绝对装入方式(Absolute Loading Mode)。并发
采用可重定位的装入方式(Relocation loading Mode)时,若是可以将不一样的的程序装入到地址范围不一样的物理内存空间,避免分配给各个程序的内存空间叠加(相交或“撞车”),就能实现将多个程序安全装入内存,使它们共享内存空间,从而支持多任务系统函数
若是使用可重定位装入方式,就必需要解决:逻辑地址对物理地址之间的转换性能
静态连接是由连接器在连接时将库的内容加入到可执行程序中的作法。 连接器是一个独立程序,将一个或多个库或目标文件(先前由编译器或汇编器生成)连接到一块生成可执行程序。操作系统
在程序运行前一次性装入指针
随着内存技术的发展,为了让更多的程序投入有限的内存并发运行,操做系统只将运行程序所必须的模块装入内存,其余诸如帮助系统等不经常使用的程序模块不装入内存,进而只装入可以使程序运行起来的那部分模块,更加节省了空间。
在程序运行时,分批装入到内存中
静态连接是由连接器在连接时将库的内容加入到可执行程序中的作法。 连接器是一个独立程序,将一个或多个库或目标文件(先前由编译器或汇编器生成)连接到一块生成可执行程序。
和静态装入是同样的。
载入时动态连接是在将功能模块读入内存时把动态库中调用到的相关模块的内容载入内存。 载入时动态连接是分别载入,当把一个模块载入内存时检查有调用关系的模块并将其载入内存,比静态连接节省了许多开销。 运行时动态连接则是把当前模块调用的模块推迟到调用的时候再载入。
在运行时和运行前进行连接。
操做系统将内存分为系统区和用户区两部分
为了支持多道程序系统和分时系统,支持多个程序并发执行,引入了分区式存储管理。
分区式存储管理是把内存分为一些大小相等或不等的分区,操做系统占用其中一个分区,其他的分区由应用程序使用,每一个应用程序占用一个或几个分区。
1 划份内存分区的方法
系统对内存的管理和控制经过数据结构—分区说明表进行。 分区说明表说明各分区号、分区大小、起始地址和是不是空闲区(分区状态)。 内存的分配释放、存储保护以及地址变换等都经过分区说明表进行。
内存分区的分配:
若是内存分区的划分不是预先划定,而是根据所要运行的程序的大小分配内存,在内存分配阶段就不会出现内存碎片。 因而,动态分区技术应运而生。
1 基本问题:
1)动态分区的基本思想:在做业执行前不直接创建分区,分区的创建是在做业的处理过程当中进行的。且其大小可随做业或进程对内存的要求而改变。 2)动态建立分区:在装入程序时按其初始要求分配,或在其执行过程当中经过系统调用进行分配或改变分区大小,按需分配。 3)采用的数据结构:内存分配表,由两个表格组成。一个是已分配区表,另外一张是空闲区表.
动态分区就有两张表来进行说明了。
动态分区分配内存时从可用表或自由链中寻找空闲区的经常使用方法
4)碎片问题
5)碎片问题的解决
动态分区很完美地在内存初次分配阶段解决了内存空间浪费的问题。可是,内存是须要重复利用的。 随着任务的不断运行完毕,内存空间会被回收;同时,操做系统又会不断接收新的任务,内存空间会被分配。
因而,当运行一个新任务时,**只能从回收回来的分区上分配内存,一方面动态分区技术在必定程度上退化为固定分区,**另外一方面分配后余下的碎片(小块的内存空间)就被保留了下来,较小的内存空间被分配出去的可能性很小,形成了浪费(碎片)。
最终,内存空间会存在不少小块的空闲空间,而再也不有大块的空闲空间,因而当较大型的任务到达时,没有足够的空间供分配(尽管这些小块的空闲内存空间之和比任务所需的空间大)
将碎片合成一大块---可重定位的动态分区
图5-10所示为指令或数据的逻辑地址到物理地址的转换过程
4 动态重定位分区的分配算法
上面的存储都是连续的内存分配技术,咱们的分页存储是离散的
与其花费巨大的代价搬家,不如离散地存储在这些碎片中
这就是汇编语言中定义一个段时大小不能够超过64KB的根本缘由。
离散存储思想产生的缘由:
离散存储的基本概念
分页存储管理的基本方法
将用户做业的地址空间分红若干个大小相同的区域,称为页面或页,并为每一个页从“0”开始编号; 相应地,**主存空间也分红与页大小相同的若干个存储块,或称为物理块或页框(frame),**而且采用一样的方式为它们进行编号,从0开始:0块,1块,…,n-1块
分页地址中的地址结构以下:
对某特定机器,其地址结构是必定的。若给定一个逻辑地址空间中的地址为A,页面的大小为L,则页号P和页内地址d可按下式求得:
在分页系统中,容许将进程的各个页离散地存储在内存的任一物理块中,为保证进程仍然可以正确地运行,即能在内存中找到每一个页面所对应的物理块,系统又为每一个进程创建了一张页面映像表,简称页表
进程在运行期间,须要对程序和数据的地址进行变换,即将用户地址空间中的逻辑地址变换为内存空间中的物理地址,因为它执行的频率很是高,每条指令的地址都须要进行变换,所以须要采用硬件来实现。页表功能是由一组专门的寄存器来实现的。一个页表项用一个寄存器。
因为页表是存放在内存中的,这使CPU在每存取一个数据时,都要两次访问内存**。第一次是访问内存中的页表,从中找到指定页的物理块号,再将块号与页内偏移量W拼接,以造成物理地址。第二次访问内存时,才是从第一次所得地址中得到所需数据(或向此地址中写入数据)。**所以,采用这种方式将使计算机的处理速度下降近1/2。可见,以此高昂代价来换取存储器空间利用率的提升,是得不偿失的。
所以,咱们采用:具备快表的地址变换机
用户把本身的做业按照逻辑关系划分为若干个段,每一个段都从0开始编址,并有本身的名字和长度。所以,程序员们都迫切地须要访问的逻辑地址是由段名(段号)和段内偏移量(段内地址)决定的,这不只能够方便程序员编程,也可以使程序很是直观,更具可读性。
在实现对程序和数据的共享时,是以信息的逻辑单位为基础的。
信息保护一样是以信息的逻辑单位为基础的,并且常常是以一个过程、函数或文件为基本单位进行保护的。
在实际应用中,每每存在着一些段,尤为是数据段,在它们的使用过程当中,因为数据量的不断增长,而使数据段动态增加,相应地它所须要的存储空间也会动态增长。然而,对于数据段究竟会增加到多大,事先又很难确切地知道。对此,很难采起预先多分配的方法进行解决。
在分段存储管理方式中,做业的地址空间被划分为若干个段,每一个段定义了一组逻辑信息。例如,有主程序段MAIN、子程序段X、数据段D及堆栈段S等。
在前面所介绍的动态分区分配方式中,系统为整个进程分配一个连续的内存空间。而在分段式存储管理系统中,则是为每一个分段分配一个连续的分区。进程中的各个段,能够离散地装入内存中不一样的分区中。为保证程序能正常运行,就必须能从物理内存中找出每一个逻辑段所对应的位置。这就须要段表了
为了实现进程从逻辑地址到物理地址的变换功能,**在系统中设置了段表寄存器,用于存放段表始址和段表长度TL。**在进行地址变换时,系统将逻辑地址中的段号与段表长度TL进行比较。若S>TL,表示段号太大,是访问越界,因而产生越界中断信号。若未越界,则根据段表的始址和该段的段号,计算出该段对应段表项的位置,从中读出该段在内存的起始地址。而后,再检查段内地址d是否超过该段的段长SL。若超过,即d>SL,一样发出越界中断信号。若未越界,则将该段的基址d与段内地址相加,便可获得要访问的内存物理地址。图示出了分段系统的地址变换过程。
(1)页是信息的物理单位,分页是为了实现离散的分配方式,以消减主存“碎片”,提升主存的利用率。或者说,分页仅仅是因为系统管理的须要,而不是用户的须要。段是信息的逻辑单位,它包含一组意义相对完整的信息。分段的目的是为了能更好地知足用户的须要。 (2)页的大小固定且由系统肯定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,于是一个系统只能有一种大小的页面。段的长度却不固定,决定于用户所编写的程序,一般由编译程序在对源程序进行编译时,根据信息的性质来划分。 (3)分页的做业地址空间是一维的,即单一的线性地址空间,程序员只须要利用一个记忆符,便可表示一个地址。分段的做业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。
段页式系统的基本原理是分段和分页原理的结合,即先将用户程序分红若干个段,再把每一个段分红若干个页,并为每个段赋予一个段名。图(a)示出了一个做业地址空间的结构。该做业有三个段:主程序段、子程序段和数据段;页面大小为 4 KB。在段页式系统中,其地址结构由段号、段内页号及页内地址三部分所组成,如图(b)所示。
在段页式系统中,为了实现从逻辑地址到物理地址的变换,系统中须要同时配置段表和页表。段表的内容与分段系统略有不一样,它再也不是内存始址和段长,而是页表始址和页表长度。图示出了利用段表和页表进行从用户地址空间到物理(内存)空间的映射。
地址变换过程:
在段页式系统中,为了便于实现地址变换,须配置一个段表寄存器,其中存放段表始址和段长TL。进行地址变换时,首先利用段号S,将它与段长TL进行比较。若S < TL,表示未越界,因而利用段表始址和段号来求出该段所对应的段表项在段表中的位置,从中获得该段的页表始址,并利用逻辑地址中的段内页号P来得到对应页的页表项位置,从中读出该页所在的物理块号b,再利用块号b和页内地址来构成物理地址。图示出了段页式系统中的地址变换机构。
要求将一个做业所有装入内存后方能运行,因而,出现了下面这样两种状况:
局部性原理:
基于局部性原理可知,应用程序在运行以前没有必要将之所有装入内存,而仅须将那些当前要运行的少数页面或段先装入内存即可运行,其他部分暂留在盘上。
当用户看到本身的程序能在系统中正常运行时,他会认为,该系统所具备的内存容量必定比本身的程序大,或者说,用户所感受到的内存容量会比实际内存容量大得多。但用户所看到的大容量只是一种错觉,是虚的,故人们把这样的存储器称为虚拟存储器。
主要的硬件支持有:
为了实现请求分页,系统必须提供必定的硬件支持。计算机系统除了要求必定容量的内存和外存外,还须要有请求页表机制、缺页中断机构以及地址变换机构。
在请求分页系统中须要的主要数据结构是请求页表,其基本做用仍然是将用户地址空间中的逻辑地址映射为内存空间中的物理地址。为了知足页面换进换出的须要,在请求页表中又增长了四个字段。这样,在请求分页系统中的每一个页表应含如下诸项
一个显而易见的事实是,随着为每一个进程所分配的物理块的减小,将使进程在执行中的缺页率上升,从而会下降进程的执行速度。最小物理块数是指能保证进程正常运行所需的最小物理块数,当系统为进程分配的物理块数少于此值时,进程将没法运行。
考虑优先权的分配算法。在实际应用中,为了照顾到重要的、紧迫的做业能尽快地完成,应为它分配较多的内存空间。**一般采起的方法是把内存中可供分配的全部物理块分红两部分:一部分按比例地分配给各进程;另外一部分则根据各进程的优先权进行分配,为高优先进程适当地增长其相应份额。**在有的系统中,如重要的实时控制系统,则多是彻底按优先权为各进程分配其物理块的。
为使进程可以正常运行,必须事先将要执行的那部分程序和数据所在的页面调入内存。如今的问题是:
事实上,在缺页中断处理时,当因为空间不足,须要置换部分页面到外存时,选择被置换页面还须要考虑到置换的代价,如页面是否被修改过。没有修改过的页面能够直接放弃,而修改过的页面则必须进行保存,因此处理这两种状况时的时间也是不一样的。假设被置换的页面被修改的几率是β,其缺页中断处理时间为ta,被置换页面没有被修改的缺页中断时间为tb,那么,缺页中断处理时间的计算公式为 t=β×ta+(1—β)×tb
在进程运行过程当中,若其所要访问的页面不在内存,而需把它们调入内存,但内存已无空闲空间时,为了保证该进程能正常运行,系统必须从内存中调出一页程序或数据送到磁盘的对换区中。但应将哪一个页面调出,须根据必定的算法来肯定。一般,把选择换出页面的算法称为页面置换算法(Page-Replacement Algorithms)。置换算法的好坏将直接影响到系统的性能。
最佳置换算法是由Belady于1966年提出的一种理论上的算法。其所选择的被淘汰页面将是之后永不使用的,或许是在最长(将来)时间内再也不被访问的页面。采用最佳置换算法一般可保证得到最低的缺页率。但因为人们目前还没法预知,一个进程在内存的若干个页面中,哪个页面是将来最长时间内再也不被访问的,于是该算法是没法实现的,但能够利用该算法去评价其它算法。
该算法是没法实现的,可是会利用该算法去评价其它算法。
FIFO算法是最先出现的置换算法。该算法老是淘汰最早进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。该算法实现简单,只需把一个进程已调入内存的页面按前后次序连接成一个队列,并设置一个指针,称为替换指针,使它老是指向最老的页面。但该**算法与进程实际运行的规律不相适应,**由于在进程中,有些页面常常被访问,好比,含有全局变量、经常使用函数、例程等的页面,FIFO算法并不能保证这些页面不被淘汰。
淘汰最早进入内存的页面,但可能那些页面也会被再次使用。因此这个算法也不太行。
FIFO置换算法的性能之因此较差,是由于它所依据的条件是各个页面调入内存的时间,而页面调入的前后并不能反映页面的使用状况。最近最久未使用(LRU)的页面置换算法是根据页面调入内存后的使用状况作出决策的。
须要的硬件支持:
可利用一个特殊的栈保存当前使用的各个页面的页面号。每当进程访问某页面时,便将该页面的页面号从栈中移出,将它压入栈顶。所以,栈顶始终是最新被访问页面的编号,而栈底则是最近最久未使用页面的页面号。假定现有一进程,它分有五个物理块,所访问的页面的页面号序列为:4,7,0,7,1,0,1,2,1,2,6
“抖动”与工做集 :
因为请求分页式虚拟存储器系统的性能优越,在正常运行状况下,它能有效地减小内存碎片,提升处理机的利用率和吞吐量,故是目前最经常使用的一种系统。但若是在系统中运行的进程太多,进程在运行中会频繁地发生缺页状况,这又会对系统的性能产生很大的影响,故还须对请求分页系统的性能作简单的分析。
因为虚拟存储器系统能从逻辑上扩大内存,这时,只需装入一个进程的部分程序和数据即可开始运行,故人们但愿在系统中能运行更多的进程,即增长多道程序度,以提升处理机的利用率。**但处理机的实际利用率却如图中的实线所示。 **
产生“抖动”的缘由:
发生“抖动”的根本缘由是,同时在系统中运行的进程太多,由此分配给每个进程的物理块太少,不能知足进程正常运行的基本要求,导致每一个进程在运行时,频繁地出现缺页,必须请求系统将所缺之页调入内存。这会使得在系统中排队等待页面调进/调出的进程数目增长。显然,对磁盘的有效访问时间也随之急剧增长,形成每一个进程的大部分时间都用于页面的换进/换出,而几乎不能再去作任何有效的工做,从而致使发生处理机的利用率急剧降低并趋于0的状况。咱们称此时的进程是处于“抖动”状态。
若是您以为这篇文章帮助到了您,能够给做者一点鼓励