操作系统—存储器管理

来源:互联网 发布:微信招聘制作软件 编辑:程序博客网 时间:2024/06/05 07:14

存储器层次结构

通用的计算机中,存储器大致分为三个层次:
①cpu寄存器
②主存
主存中又包含了:高速缓存、主存、磁盘缓存
③辅存
辅存包括了磁盘和可移动存储介质
操作系统对这么存储器进行统一管理。

程序的装入和链接

首先源代码需要通过编译生成目标代码、在通过链接将一些库函数链接在一个生成可执行程序,最后再将程序装入内存。
程序链接
源程序编译后得到一些目标模块,需要通过链接程序将目标模块和一些库函数和链接形成装入模块。在链接时需要进相对地址进行修改,变换外部调用符号(将调用符号改成程序的相对地址)。
①静态链接:在程序运行之间就将模块和库函数链接起来。
②装入时动态链接:在程序装入内存时,边装入,边链接(动态时链接可以完成对目标模块的共享)。
③运行时动态链接:在目标模块运行到时再进程链接。
程序装入
运行程序需要将程序装入内存,程序的装入有绝对装入、可重定位装入、动态运行时装入。
①绝对装入方式:
绝对装入的方式要求在编译时就知道程序在运行时会驻留在内存的哪个位置,在程序进入内存后,逻辑地址和实际内存地址是完全一样的。
②可重定位装入方式
很明显,绝对装入方式非常不方便,编译程序不可能预知到程序最后的运行地址。采用可重定位的装入方式是在编译程序时,程序都是从逻辑0地址开始的,在装入程序时,对程序中地址进行修改,把逻辑地址转变为真实地址。
③动态运行时装入方式:
可重定位装入方式是在装入时对地址进行转换,但是程序在运行时,内存地址可能会发生变动,那么就产生了动态运行时转入,在程序执行时再对逻辑地址进行一个转换。

内存分配

程序载入在内存中,那么操作系统就要给程序分配内存,分配内存的方式一般又如下几种:
①连续分配方式
②基本分页存储管理方式
③基本分段存储管理方式
④请求分页存储管理方式
⑤请求分段存储管理方式

连续分配方式

连续分配就是把一个程序分配在一块连续的内存区域。
连续分配又可以分为:

  • 单一连续分配
    这是最简单的分配方式,这个只适合单用户、单任务的操作系统。把内存分成系统区和用户区,同时只有一个任务在内存中运行,不需要考虑太多,所以分配方便。
  • 固定分区分配
    将内存空间分割成多个固定的、不同大小的内存区域,操作系统管理着一个内存分配表,当程序要装入时,在内存分配表中查找是否有符合大小的内存空间,如果没有,那么就拒绝分配。这是最早的多道程序的内存分配机制。但是分区大小固定,会造成内存空间的浪费。
  • 动态分区分配
    动态分区分配是根据进程实际需要分配适合的内存空间。主要有内存的动态分配和回收。一般操作系统会采用空闲分区表或者空闲分区链来维护内存空间的分配信息。分区表由已分配区表和未分配区表组成,分区表会记录每块分区的起始地址和分区大小等数据项。空闲分区链是在每个分区的首尾的三个字中设置控制分区的分配信息,以及链接分区的前向指针,在分区尾部有尾向指针。在分区分出去之后将状态进行修改。
    分区分配算法
    ①首次适应算法
    首次适应算法是按照顺序搜索适合大小的内存空间,只要第一次搜索到就把内存空间划分给作业。这种方式很快速,简单,但是低地址内存不断被划分,会留下很多内存碎片。
    ②循环首次适应算法
    这种算法是从上一次分配空间的下一个分区开始查找第一次适合的内存分区,如果查到就划分给作业。如果到结尾还没查到,那么就从头开始。这种方式使内存分配分布得更均匀。
    ③最佳适应算法
    最佳适应算法是找到一个和申请空间大小最匹配的内存分区分配给作业。但是这种方式可能会留下很多细小的内存碎片。
    ④最坏适应算法
    最坏适应算法是找到一个最大的足够分配的内存分区分给作业。这样留下的分区会比较大,不会造成小的内存碎片。但是可能会造成最终剩下的内存分区不够大。
    ⑤快速适应算法
    这种算法根据分区不同的大小进行分类,将同一类的分区链接在一起,在请求内存空间分配时,根据申请的大小在相对的分类中查找,同时在进行分配时不会对分区进行分割,这样就不会产生内存碎片。
  • 动态重定位分配
    由于剩余的分区可能不满足申请空间的大小,那么就要对已经在内存中的程序进行移动,将小的分区进行合并。这时就引入了动态重定位分配,动态重定位依赖于程序动态运行时转入,在程序运行的时候才对逻辑地址相对地址和物理地址进行一个转换。为了运行更快,需要有一个重定位寄存器,物理地址是逻辑地址在重定位寄存器值上的一个叠加,这样就可以方便的移动程序,将合并出来剩余的空间分配给进程。
    对换
    对换实际上是当内存不够用时,将内存中阻塞暂时不能运行的进程调到外存当中。外存分为文件区和对换区,文件区采用离散分配,对换区采用连续分配的方式,空间分配算法与内存相似。对换又有整个进程的对换,还有分页对换和分段对换。当进程需要更多内存空间而空间不足时,操作系统就会将处于阻塞状态且优先级低的进程换出,当对换区有就绪的进程时,先将处于对换区时间最久的进程换到内存中。

基于分页存储管理方式

由于连续分配会产生内存碎片,而紧凑的方式又会有效率的问题,所以有了离散分配。分页存储管理方式就是一种离散分配。 基本分页管理方式不具有页面对换功能,也不支持虚拟存储管理,只有当所有的页存在于内存中,程序才能运行。
:分页存储管理将进程的逻辑地址划分为若干个大小的片,称为页。将内存空间划分为与页一样大小的若干个存储块,称为块。
分页后,地址结构高位一部分为页号,低位为页内地址。
页表:为了程序的页面能和实际的内存物理块号对应起来,系统为每个进程分配了一个页表。将程序的页号和实际的物理内存块号所对应起来。
地址变换机构:地址变换机构是将程序的逻辑地址转换为实际的物理地址,将逻辑地址中的页号根据页表转换为对应的实际内存块号。虽然寄存器访问快,但是页表项会很多,所以页表项大多放在内存中, 只留一个页表寄存器来存页表的始址和页表的长度。
当进程要访问某逻辑地址的数据时,将页表始址+页号*页表项长度取出块号,然后和页内地址组合得出真实的物理内存地址。
快表:上面的这种方式还是有效率问题,需要两次访问内存,所以增加了一个快表,快表实际上是一个高速缓冲寄存器,寄存器中存着之前访问过的地址,如果下一次在块表中有页号所对应的块号,那么直接取出,这样就不用去访问内存。
二级页表和多级页表
由于页表规模的增大,页表对内存空间的要求也增大了,可能难以找到一块连续的内存空间来存放页表。
可以采用二级和多级页表,将页表项分散开来,这样页表项可以不需要连续的内存空间,离散在内存中。

基本分段存储管理方式

分段的机制是为了满足程序员编程需要。用户经常把自己的作业或者说程序按照逻辑关系分为若干个段。同时动态链接也需要以段作为单位。
在分段存储的管理方式中,作业的地址空间根据逻辑信息被分为若干段。分段地址有段号和段内地址,这个跟分页是有点相似的。
系统会为程序的每一段分配连续的内存空间。而段与段之间是离散的分布在内存当中。分段机制也是有段表。由于段不像分页那样大小固定,所以在段表中会有段长和段的基址。基址指向该段所在的实际的内存物理地址。
而在地址变换时,是将段号替换成了段的基址,当然在这之前会先检查段内空间是否超了段的长度。
分页是系统需求,而分段是用户需求,优化了编程提高了效率。
段页式存储管理方式
分段和分页都有各自的优点和缺点。所有有了段页式存储,先将程序分段,然后将该段分页。
在这种模式下,地址被分为了段号、段内页号、页内地址。
在进行地址转换时,先根据段号在段表中找到对应的页表,然后在页表中再根据段内页号找到对应的块号,然后将块号和页内地址结合得出最终的内存物理地址。

虚拟存储器

由于现代的程序越来越大,所需求的内存空间已经超过了内存的总容量。这时候就引入了虚拟存储器,从逻辑上去拓展内存容量。
虚拟存储器是具有请求调入功能和置换功能,能从逻辑上对内存容量扩展的一种存储器系统。
在以前的存储管理当中,只有当一个作业一次性装入内存才能运行。在虚拟存储器下,可以只将运行的一部分程序装入内存运行,而另一部分可以留在外存,当需要运行到时,再从外存中调出来。

请求分页存储管理方式

硬件支持
①页表机制:这个页表跟基本分页有所不同,这个页表更为详细复杂。
页表项包括页号、物理块号、状态位P、访问字段A、修改位M、外存地址。
状态位P是表示该页否已经调入内存。
访问字段中记录本页在一段时间内被访问的次数或者最近已经有多长时间未被访问。
修改位:记录在调入内存后是否被修改过,由于内存每一页都在外存上由副本,如果没有被修改过,那么在置换时不需要当该页重新协会到外存上。
②缺页中断机制:
当访问的页面不存在时就需要从外存中将页面调度到内存,这时会产生一个缺页中断,先进程cpu环境保护,然后跳转到中断程序运行,最后恢复cpu环境。
③地址变换机制
这个跟基本分页的机制基本相似。
页面置换算法
当缺页时需要从外存调入页面,这时内存不足,就需要将部分页面调出到外存。通常将选择页面调出的算法称为页面置换算法。
最佳置换算法
首先该算法是无法实现的,但是思想值得借鉴,选择置换出的页面是以后永久不使用的或者在未来很长时间都不会被访问的。
先进先出页面置换算法
当内存不够时,将最先进入内存的页面换出,但是有些页面是会被经常访问的,所以效率很低,但是在算法实现上比较简单。
最近最久未使用置换算法(LRU)
顾名思义,这个算法是将最近最久没有使用的页面置换出去,该算法赋予每个页面一个访问字段,用来记录上次访问到现在的时间t,当需要进行置换时,选择t最大的进行换出。最近最久未使用也许会代表将来也不会使用,是利用了最佳置换算法的逆向思想,但这个结果不是绝对的,很多东西是无法预测的。
算法的实现可以靠寄存器或者栈实现,例如用寄存器实现,寄存器用来存时间的代表值,定时将寄存器中的值向右移动一位。访问页面时,将相应的寄存器值清零。
栈的实现:当页面被访问到时,将页面从栈中移除,然后压入栈顶,那么栈底的页面就是最近最久未使用的页面。
Clock置换算法
LRU算法有较多的硬件支持,所以用的比较广泛的就是LRU的近似算法Clock算法。
这种算法是给页面增加一个标识位,当某页被访问时,访问位则置1,在选择页面换出时,如果页面访问位为0,那么就选择该页换出,如果访问位为1,那么将它置为0,根据FIFO算法继续访问下一个页面。如此往复循环的访问,当有页面是0时,则将该页面换出。
改进:在选择页面换出时,既要是未使用过的页面,又要是未被修改过的页面,这两个条件同时满足的作为首选页换出。

请求分段存储管理方式

分段和分页的机制其实是差不多的,只不过分段是根据段的基址来进行寻找。而分页是根据内存块号去寻找。
分段中还有共享段表的应用。

原创粉丝点击