操作系统——存储管理(2)

来源:互联网 发布:软件创业成功案例 编辑:程序博客网 时间:2024/05/02 04:30

4、页式和段式存储管理

4.1页式存储管理

为什么提出页式存储管理?
分区存储管理方案的一个特点就是连续性,即系统对每个程序都分配一片连续的内存区域。这种连续性会导致碎片的问题。固定分区肯定会导致内碎片问题。可变分区会导致外碎片问题,即使可以通过内存紧缩技术来解决,但是合并碎片的时候需要花费大量的CPU时间。
总之,无论是内碎片还是外碎片,它们的存在都降低了内存资源的使用效率。所以,为了解决这种问题,提出了页式存储管理方案,打破存储分配的连续性,使得一个程序的逻辑地址空间可以分布在若干个离散的内存块中,从而提高内存利用率。
  • 基本原理
基本思路:一方面,把物理内存划分为许多个固定大小的内存块,称为物理页面或页框(page frame),另一方面,把逻辑地址空间也划分为大小相同的块,称为是逻辑页面或简称为页面(page)。
如果需要运行一个大小为n个页面的程序,那么就需要有n个物理页面把它装进来。当然,这些物理页面不一定是连续的。也就是说,对于每一个进程来说,虽然逻辑地址空间是一个连续的一维地址空间,所有的逻辑页面也都是连续的。但是在装入到内存后,这些逻辑页面在内存中的存放位置就不一定是连续的,而很可能是分散的。

需要解决的问题:
①用于存储管理的数据结构是什么?
②当一个进程到来时,如何为它分配内存?
③当一个进程运行结束后,释放它所占用的内存空间后,系统如何回收内存?
④当一个进程被加载到内存后,它如何才能正确地运行?这主要是指如何把程序当中使用的逻辑地址转换为内存中使用的物理地址,即地址映射问题。
  • 数据结构
在页式存储管理中用到的第一个数据结构是页表。系统会为每一个进程都建立一个页表,页表给出了逻辑页面号和具体的内存块号,即物理页面号之间的对应关系。
页表是保存在内存中的,并且是在操作系统的内核空间,是属于操作系统的数据结构,用户不能随便访问。
在MMU(存储管理单元)中的页表基地址寄存器中,存放了这个进程的页表的起始地址。把逻辑页面号与这个基地址寄存器的值相加,就找到了相应的页表项,里面记录了这个逻辑页面所对应的物理页面号。

页表     物理页面号    物理页面号    物理页面号............................................................    物理页面号
页表可以用一个一维数组来实现,下标表示连续的逻辑页面号,每个表格中存放的就是每一个逻辑页面号对应的物理页面号。

在页式存储管理中用到的第二个数据结构是物理页面表。在系统中设立一张物理页面表,用来描述内存空间中各个物理页面的分配使用情况。在具体实现上,可以采用位示图和空闲页面链表等方法。
位示图:假设整个内存被分为256个物理页面,那么可以用8个字长为32位的字来表示256个物理页面的使用情况(共256个位)。位值为0表示对应的物理页面空闲,位值为1表示对应的物理页面被占用。最后,增加一个字段,用来表示剩余的空闲的物理页面数目。

基于位示图的物理页面表                                                                                                                                                                                                                                                                                                
  • 内存的分配与回收
以位示图为例,内存的分配过程:
①对于一个新的进程,计算它所需要的页面数N。然后查看位示图,看是否还有N个空闲页面。
②如果空闲的物理页面够用,就申请一个页表,其长度为N,并把页表的起始地址填入到该进程的PCB中。
③分配N个空闲的物理页面,并将它们的编号填入到页表中,这样,就建立了逻辑页面与物理页面之间的对应关系。
④修改位示图,对于那些已经被占用的物理页面,把它们对应位的值,从0变为1,表示已经被占用,然后把空闲页面数减去N。

当一个进程运行结束的时候,就需要释放它占用的内存空间,需要对这样物理页面进行回收,具体过程是:
①对于每一个物理页面,根据其编号计算出它在位示图中的相应位置。
②将相应位的值从1变为0,表示该页面已经空闲。
③修改位示图的物理页面数,把它加上N。

  • 地址映射
在页式存储管理中,地址映射可以分为3个步骤:
①对于给定的逻辑地址,找到逻辑页面号和页内偏移地址;
如果逻辑地址以10进制计算的话:
逻辑页面号 = 逻辑地址   /   页面大小
页内偏移     = 逻辑地址  % 页面大小
②根据逻辑页面号去查找页表,找到它所对应的物理页面号;
在MMU(存储管理单元)中的页表基地址寄存器中,存放了这个进程的页表的起始地址。把逻辑页面号与这个基地址寄存器的值相加,就找到了相应的页表项,里面记录了这个逻辑页面所对应的物理页面号。

为了能够访问页表当中的内容,在硬件上要增加一对寄存器,即页表基地址寄存器和页表长度寄存器。页表基地址寄存器用来指向页表的起始地址,页表长度寄存器用来指示页表的大小,即在这个进程中,有多少个页面。

③根据物理页面号和页内偏移地址,计算最终的物理地址。
把物理页面号放在高端,把页内偏移放在低端地址,这样就得到了物理地址。




采用这种方法,如果要读取内存中的一个数据或一个指令,需要访问2次内存。第一次是访问页表,第二次是真正访问目标。这就大大降低了访问内存的速度。
如何提高速度呢?

由于在程序的运行中,在一段时间里,一般集中地访问一小部分页面。因此,对于进程的页表来说,在一段时间里,只有一小部分的页表项会被经常地访问。根据这种现象,给计算机增加了一个特殊的快速查找硬件(TLB,Translation Lookaside Buffer),用来存放最近一段时间内最经常用的那些页表项。TLB可以直接把逻辑页面号映射为相应的物理页面号,而不用访问内存中的页表,这样就缩短了页表的查询时间。
具体实现过程:

当一个逻辑地址到来时,系统首先在TLB中查找,看看它的逻辑页面号所对应的页表项是否包含在TLB中。如果能够找到,那么就直接从TLB中把相应的物理页面号取出来,并且与页内偏移合成最终的物理地址;如果没有找到,则按照原来的方式去得到物理地址,并且访问完之后,还要把刚刚访问过的那个页表项添加到TLB中。

4.2段式存储管理

首先我们要知道为什么要提出段式存储管理?什么是段式存储管理?

①前面提出的各种存储方案:固定分区,可变分区,页式存储管理,它们都有且只有一个逻辑地址空间,即一维的线性连续空间。但是从程序员的角度来讲,程序的结构应该是由一组模块或片段组成,每个片段是一个逻辑单元,如主程序,全局变量,栈和库函数等等
②把程序分布在不同的逻辑单元,存储保护比较方便,可以针对不同的内容,设置不同的保护模式。比如:对于代码段我们设置为可读和可执行,对于数据段我们设置为可读,可写,对于栈(包括函数调用时的形参,局部变量,CPU寄存器的值,调用者的返回地址等)我们应该设置为可读可写。
③把程序分布在不同的逻辑单元,便于存储共享。
基于这些原因,提出了段式存储管理。

  • 基本原理
段式存储的基本思路是:一方便,在逻辑地址空间中,对于程序中的每一个逻辑单元,设立一个完全独立的地址空间,称为段。在每个段的内部,是一个一维的连续的地址空间。一般来说每个段的大小是不相等的,它们所包含的内容也是不同的,如代码段,数据段,堆,栈等。
另一方面,对于物理内存来说,对它的管理采用的就是前面介绍的可变分区的存储管理方法。当一个程序需要装入到内存中时,以段为单位进行分配,把程序中的每一个段都装入到一个内存分区中,这些内存分区不要求是连续的。
总之,当一个程序被装入到内存中以后,它的每一个段都被存放在一个独立的内存分区中。

  • 具体实现
在段式存储管理中,由于每一个程序都是由若干个段组成,而每一个段都是一个独立的地址空间。因此,为了指出逻辑地址空间中的某个地址,就必须给出一个二元地址,包括这个段在程序中的段号(也就是这个段在程序中的编号),还有段内偏移地址。也就是说,把逻辑地址一分为二,高端部分表示段号,低端部分表示段内偏移。
例如:早期的8086处理器,将段号存放在段寄存器(CS,DS,SS,ES等).

系统为每一个进程都建立一个段表,它给出了进程中的每一个段与它所对应的内存分区之间的映射关系。

段表的例子段号内存分区的起始地址段长0 140010001630040024300400
为了访问段表里面的内容,在硬件上增加了两个寄存器,一个是段表基地址寄存器,用来指向内存中段表的起始地址;另一个是段表长度寄存器,用来指示段表的大小,即在这个程序中包含的段的个数。


4.3页式管理和段式管理的比较

  • 分页是出于系统管理的需要,分段是出于用户应用的需要。页式存储管理,为了减少碎片,把内存划分为许多个固定大小的物理页面,同时把逻辑地址空间划分为大小相同的逻辑页面。段式存储管理是为了实现程序中各个逻辑单元的独立性,便于它们的共享、保护和修改,从而为每一个逻辑单元设立一个独立的段。
  • 页面的大小是固定的,而段的大小是不固定的。
  • 页式存储管理中,逻辑地址是一维的线性连续的地址。段式存储管理中,逻辑地址是二维的,一维是段号,一维是段内偏移。

4.4、段页式存储管理

  • 段式和页式存储各有特点。段式存储为用户提供了一个二维的逻辑地址空间,可以满足程序和信息的逻辑分段要求,反映了程序的逻辑结构,从而有利于段的共享、保护和动态增长页式存储把内存分成一个个页面,从而克服了碎片的问题,提高了内存的利用率。把两种方案结合起来,就是段页式存储管理。
  • 基本思路:先把程序划分为段,然后在段里进行分页。它的逻辑地址分为两个部分,一个部分是段号,另一个部分是段内偏移,这和普通的段式存储管理是一样的。但是对于段内偏移又被分成两个部分,一个是逻辑页面号,另一个是页内偏移地址,这和普通的页式存储管理是一样的。物理内存的管理上,它是按照页式存储管理方案来进行,而且在内存的分配上,也是以页面为单位来进行分配。


在具体的实现上,需要几个数据结构:
①段表,它里面记录的是每一个段的页表起始地址和页表长度,而不是普通段式存储那样,记录的是这个段所在的内存分区的起始地址。
②页表,它和普通的页式存储管理一样,记录了逻辑页面号与物理页面号之间的对应关系。但是特殊在于,每一个段都有一个页表,因为在一个程序当中可能会有多个段,所以就可能会有多个页表。

在硬件方面,需要两个寄存器,一个是段表基地址寄存器,用来指向内存当中段表的起始地址;另一个是段表长度寄存器,用来指示段表的大小,即程序中段的个数。

在段页式存储管理方案中,如果从内存中取一条指令或读一个数据,就必须访问内存3次。第一次是访问段表,第二次是访问页表,第三次是真正去访问目标数据。


0 0