一. 存储器的层次结构

1.1 多层结构的存储器系统

1.1.1 存储器的多层结构

  1. 在存储层次中,层次越高,存储介质的访问速度越快,价格越高,相对所配置的存储容量也越小
  2. 其中的寄存器、高速缓存、主存储器和磁盘缓存均属于操作系统存储管理的管辖范畴,掉电后它们中存储的信息不再存在
  3. 低层的固定磁盘和可移动存储介质则属于设备管理的管辖范畴,它们存储的信息将被长期保存

1.1.2 可执行存储器

  1. 在计算机系统的存储层次中,寄存器和主存储器又被称为可执行存储器
  2. 进程可以在很少的时钟周期内使用一条load或store指令对可执行存储器进行访问,但对辅存的访问则需要通过I/O设备实现,因此,在访问中将涉及到中断、设备驱动程序以及物理设备的运行,所需耗费的时间远远高于访问可执行存储器
  3. 对于不同层次的存储介质,由操作系统进行统一管理,操作系统的存储管理负责对可执行存储器的分配、回收,以及提供在存储层次建数据移动的管理机制,如主存与磁盘缓存,高速缓存与主存间的数据移动等
  4. 设备和文件管理则是根据用户的需求,提供对辅存的管理机制

1.2 主存储器和寄存器

1.2.1 主存储器

  1. 主存储器简称内存或主存,是计算机系统中的主要部件,用于保存进程运行时的程序和数据,也称可执行寄存器
  2. 通常,处理机都是从主存储器中取得指令和数据的,并将其所获得的指令放入指令寄存器中,或者反之,将寄存器中的数据存入到主存储器
  3. 由于主存储器访问速度远低于CPU执行指令的速度,为了缓和这一矛盾,在计算机系统中引入了寄存器高速缓存

1.2.2 寄存器

  1. 寄存器具有与处理机相同的速度,所以对寄存器的访问速度最快,完全能与CPU协调工作
  2. 早起计算机中,寄存器数目只有几个,主要用于存放处理及运行时的数据,以加速存储器的访问速度如使用寄存器存放操作数,或用作地址寄存器加快地址转换速度等

1.3 高速缓存和磁盘缓存

1.3.1 高速缓存

  1. 高速缓存是现代计算机结构中的一个重要部件,它是介于寄存器和存储器之间的存储器,主要用于备份主存中较常用的数据,以减少处理机对主存储器的访问次数,大幅度的提高程序执行速度
  2. 高速缓存容量远大于寄存器,而比内存约小两到三个数量级左右
  3. 通常,进程的程序和数据存放在出存储器中,每当要访问时,才被临时复制到一个速度较快的高速缓存中。这样,当CPU访问一组特定信息时,首先先检查它是否在高速缓存中,如果已经存在,便可直接从中取出,以避免访问主存,否则就必须从主存中读出信息

1.3.2 磁盘缓存

  1. 目前磁盘的I/O速度远低于对主存的访问速度,为了缓和两者之间速度上的不匹配,设置了磁盘缓存,主要用于暂时存放频繁使用的一部分磁盘数据和信息,以减少访问磁盘的次数
  2. 磁盘缓存和告诉缓存不同,它本身并不是一种实际存在的存储器,而是利用主存中的部分存储空间暂时存放从磁盘中读出(或写入)的信息
  3. 主存也可以看作是辅存的高速缓存,因为辅存中的是数据必须复制到主存中才可以使用,反之,数据也必须先存在主存中,才能输出到辅存

二. 程序的装入和链接

用户程序要在系统中运行,必须先将它装入内存,再将它转为一个可以执行的程序,通常需要以下三步

  • 编译:由编译程序(Compiler)对用户源程序进行编译,形成若干个目标模块(Object Module)
  • 链接:由链接程序(Linker)将编译后形成的一组目标模块以及它们所需要的库函数链接在一起,形成一个完整的装入模块(Load Module)
  • 装入:由装入程序(Loader)将装入模块装入内存

2.1 程序的装入

2.1.1 绝对装入方式

  1. 当计算机系统很小,且能运行单道程序时,完全有可能知道程序将驻留在内存的什么位置,此时可以采用绝对装入方式,用户编译后,将产生绝对地址(即物理地址)的目标代码
  2. 如,事先已知用户程序(进程)驻留在从R处开始的位置,则编译程序所产生的目标模块(即装入模块)便可从R处开始向上扩展。绝对装入程序便可按照装入模块的地址,将程序和数据装入内存
  3. 用户程序中所使用的的绝对地址既可在编译或汇编时给出也可由程序员直接赋予。但后者对程序员要求高,且灵活性差,所以通常使用符号地址,然后在编译或汇编时,再将这些符号地址转换为绝对地址

2.1.2 可重定位装入方式

  1. 在多道程序环境下,编译程序不可能预知编译后所得到的目标模块应该放在内存的何处**(编译前不知物理起始位置)**
  2. 程序中的其他地址都是相对于起始地址算的,默认起始是0 (物理起始1000,数据物理实际是1100,程序用的逻辑是100)
  3. 把在装入时对目标程序中指令地址数据地址的修改称为重定位,又因为地址变换通常是在进程装入时一次完成,以后不再改变,所以又叫静态重定位

2.1.3 动态运行时的装入方式

  1. 可重定位装入方式可将装入模块装入到内存中任何允许的位置,但不允许程序运行时在内存中移动位置
  2. 实际中,运行过程中程序和数据的地址(物理,绝对地址)在内存中经常要改变,如在具有对换功能的系统中,一个进程可能多次换出又多次换入,每次换出换入后地址通常是不同的
  3. 动态运行时装入程序在吧装入模块装入到内存后,并不立即把装入模块中的逻辑地址转换为物理地址,而是推迟到程序真正执行时才进行。因此,装入内存后的所有地址都仍是逻辑地址
  4. 为了使地址转换不影响指令的执行速度,这种方式需要一个重定位寄存器的支持,详见下文

2.2 程序的链接

源程序经过编译后,可得到一组目标模块。链接程序的功能是将这组目标模块以及他们所需要的库函数装配成一个完整的装入模块。对目标模块进行链接时,有以下三种方式

2.2.1 静态链接方式

在程序运行之前,现将各目标模块及它们所需的库函数链接成一个完成的装配模块,以后不再拆开

例子

  • 编译后得到三个目标模块A、B、C,它们的长度分别为L、M、N
  • A调用了B,B调用了C
    需解决以下两个问题
  1. 对相对地址进行修改。在由编译程序所产生的的所有目标模块中,使用的都是相对地址,即起始位置都为0,每个模块中的地址都是相对于起始地址计算的。在连接成一个装入模块后,原模块 B 和 C 在装入模块的起始地址不再是0,而分别是 L 和 L+M,所以需要修改B和C中的相对地址,即把原B中的所有相对地址都加上L,把原C中所有相对地址都加上L+M
  2. **变换外部调用符号。**将每个模块中所用的外部调用符号也都变换为相对地址,如把B的起始地址变换为L,把C的地址变换为L+M。

2.2.2 装入时动态链接

  1. 编译后得到一组目标模块,在装入内存时,采用边装入边连接的链接方式
  2. 即在装入一个目标模块时,若发生一个外部模块调用事件,将引起装入程序去找出相应的外部目标模块,并将它装入内存
  3. 动态连接方式有以下优点:
  • 便于修改和更新:对于静态链接装配在一起的装入模块,若想要修改其中的某个目标模块,则要求重新打开装入模块,这不仅低效,有时候甚至是不可能的。若采用动态链接,由于各目标模块是分开存放的,所以要修改或更新个目标模块是非常容易的事
  • 便于实现对目标模块的共享:在采用静态链接方式是,每个应用模块都必须含有其他目标模块的拷贝,无法实现对目标模块的共享。但采用装入时动态链接方式时,OS很容易将一个目标模块连接到几个应用模块上,实现多个应用程序对该模块的共享

2.2.3 运行时动态链接

  1. 在许多情况下,应用程序在运行时,每一次要运行的模块可能是不同的,但由于事先无法知道本次要运行哪些模块,所以只能是将所有可能要运行到的模块都装入内存,并在装入时全部连接在一起。显然是低效的
  2. 如错误处理用的模块,如果程序在运行时不会出错,则显然不会应用到该模块
  3. **运行时动态链接:**将模块的链接推迟到程序执行时才进行。即在执行过程中,当发现一个被调用模块尚未装入内存时,立即由OS找到该模块,并将其装入内存,将其连接到调用者模块上。
  4. 不仅加快程序的装入过程,而且可节省大量的内存空间

三. 连续分配存储管理方式

  1. 为了能将用户程序装入内存,必须为它分配一定大小的内存空间。
  2. 连续分配方式是最早出现的一种存储器分配方式,该分配方式为一个用户程序分配一个连续的内存空间,即程序中代码或数据的逻辑地址相邻,体现在空间分配时物理地址的相邻。
  3. 连续分配的方式可分为四类:单一连续分配固定分区分配动态分区分配动态可重定位分区分配算法

3.1 单一连续分配

  1. **单一连续分配:**单道环境下,当时的存储器管理方式是把内存分为系统区和用户区两部分,系统区仅提供给OS使用,通常放在内存的低址部分,而在用户区内存中,仅有一道用户程序,即整个内存的用户空间由该程序独占。

3.2 固定分区分配

  1. 为了能在内存中装入多道程序,且使这些程序之间又不会相互干扰,于是将整个用户空间划分为若干个固定大小的区域,在每个分区之装入一道作业。这是最早的,最简单的一种可运行多道程序的分区式存储管理方式
  2. 如果内存中有4个用户分区,便允许四个程序并发执行,当一有空闲分区时,便可以再从外存的后备,作业队列中选择一个适当大小的作业,装入该分区。

3.2.1 划分分区的方法

可用下述两种方法将内存的用户空间划分为若干个固定大小的分区

  1. 分区大小相等:缺点是缺乏灵活性,但是对于利用一台计算机同时控制多个相同对象的场合,因为这些对象所需的内存空间大小往往相同,这种划分方式比较方便和实用
  2. 分区大小不等:增加了存储器分配的灵活性,最好能对常在系统中运行的作业大小进行调查,根据用户的需要来划分

3.2.2 内存分配

  1. 为了便于内存分配,通常将分区按其大小进行排队,并为之建立一张分区使用表,其中各表项包括每个分区的起始地址、大小及状态
  2. 如下图,当有用户程序要装入的时候,由内存分配程序依据用户程序的大小检索该表,从中找到一个能满足要求的尚未分配的分区,将其分配给该程序,并将表中状态置为已分配。若未找到大小足够的分区,则拒绝为该用户程序分配内存


3. 由于每个分区的大小固定,所以必然会造成存储空间的浪费,因此现在已很少将它用于通用的OS中

3.3 动态分区分配

动态分区分配又称为可变分区分配,它是根据进程的实际需要,动态的为之分配内存空间。实现动态分区分配时,涉及到分区分配中所用的数据结构分区分配算法分区的分配与回收操作这三方面问题

3.3.1 动态分区分配中的数据结构

为了实现动态分区分配,系统中必须配置相应的数据结构,用以描述空闲分区和已分配分区的情况,通常数据结构有以下两种形式

  1. 空闲分区表:在系统中设置一张空闲分区表,用于记录每个空闲分区的情况,每个空间分区占一个表目,表目中包括分渠道、分区大小和分区始止等数据项
  2. 空闲分区链:为了实现对空闲分区的分配和连接,每个分区的起始部分设置一些用于控制分区的信息,以及用于连接各分区所用的前向指针,在分区尾部设置一向后指针,通过前、后向链接指针,可将所有的空闲分区链接成一个双向链。为了检索方便,前后都设置了状态位和分区大小。0表示未分配,1表示已分配

3.3.2 动态分区分配算法

把一个新作业装入内存,必须按照一定的分配算法,从空闲分区表或空闲分区连中选出一分区分配给该作业。各种动态分区分配算法将在下文中讲述

3.3.3 分区分配操作

动态分区存储管理中,主要的操作是分配内存和回收内存

3.3.3.1 分配内存

  1. 系统应利用某种分配算法,从空闲分区链(表)中找到的所需大小的分区
  2. 请求的分区的大小为 u.size,表中每个分区的大小表示为 m.size最小的,不可再分割的分区大小是size
  3. 如果 m.size - u.size <= size,说明剩余部分太小,不可再切割,直接将整个分区分配给请求者
  4. 否则,从该分区中按请求的大小划分出一块内存空间出去,余下的部分仍留在空闲分区链(表)中,然后将分配区的首址返回给调用者

3.3.3.2 回收内存

当进程运行完毕释放内存时,系统根据回收区的首址,从空闲区链(表)中找到相应的插入点,因此可能出现以下四种情况之一

  1. 回收区与插入点的前一个空闲分区F1相邻接。此时应将回收区与插入点的前一分区合并,不必为回收分区分配新表项,而只需修改其前一分区F1的大小
  2. 回收分区与插入点的后一空闲分区F2相邻接,此时也可将两分区合并,形成新的空闲分区,但用回收区的首址作为新空闲区的首址,大小为两者之和
  3. 回收区同时与插入点的前、后两个分区邻接,此时将三个分区合并,使用F1的表项和F1的首址,大小为三者之和
  4. 回收区既不与F1邻接,又不与F2邻接,这时应为回收区单独建立一个新表项,填写回收区的首址和大小

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

为了实现动态分区分配,通常是将系统中的空间分区链接成一个链。所谓顺序搜索,是指亿次搜索空闲分区链上的空闲分区,寻找一个大小能满足要求的分区。基于顺序搜索的动态分区算法有如下四种:首次适应算法循环首次适应算法最佳适应算法最坏适应算法

3.4.1 首次适应算法

  1. 该算法要求空闲分区链以地址递增的次序链接
  2. 在分配内存时,从链首开始顺序查找,知道找到一个大小能满足要求的空闲分区为之。再按照作业的大小,从分区中划出一块内存空间,分配给请求者,余下的留在空闲链中,若找不到则说明系统已没有足够大的内存分配给该进程,内存分配失败
  3. 该算法倾向于优先利用内存中低址部分空闲分区,从而保留了高址部分的大空闲区
  4. 其缺点是低址部分不断被划分,会留下许多难以利用的、很小的空闲分区,即碎片。且由于每次都是从低址开始,小碎片多留于低址,增加查找可用空闲分区的开销

3.4.2 循环首次适应算法

  1. 为进程分配内存空间时,不再是每次都从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找
  2. 该算法要求设置一个起始查询指针,用于指示下一次起始查询的空闲分区,并采用循环查找方式,即链尾找不到会回到链头
  3. 找到后,应调整起始查询指针
  4. 该算法能使内存中的空闲分区分布的更均匀,减少了查找空闲分区时的开销,但是会缺乏大的空闲分区

3.4.3 最佳适应算法

  1. 每次为作业分配内存时,总是能把满足要求,又是最小的空闲分区分配给作业
  2. 为了加速寻找,该算法要求将所有的空闲分区按其容量以小到大的顺序形成一空闲分区链,这样第一次找到的能满足要求的空闲区必然是最佳的
  3. 缺点是每次分配后切割下来的剩余部分总是最小的,这样在存储器中会留下许多难以利用的碎片

3.4.4 最坏适应算法

  1. 每次为作业分配内存时,总是挑选一个最大的空闲区,从中分割一部分存储空间给作业使用
  2. 该算法要求将所有的空闲分区按其容量从大到小的顺序形成一个空闲分区链,查找时只看第一个分区能否满足要求即可,效率较高
  3. 缺点是存储器会缺乏较大的空闲分区

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

  1. 基于顺序搜索的动态分区分配算法,比较适用于不太大的系统,当系统很大时,系统中的内存分许可能会很多,相应的空闲分区链就可能很长,这时采用顺序搜索分区方法可能会很慢
  2. 中、大型系统中往往采用基于索引搜索的动态分区分配算法,目前常用的有快速适应算法伙伴系统哈希算法

3.5.1 快速适应算法

  1. 该算法又称分类搜索算法,是将空闲分区根据其容量大小进行分类,对于每一类具有相同容量的所有空闲分区,单独设立一个空闲分区链表,这样系统中存在着多个空闲分区链表
  2. 同时,内存中设立一张管理索引表,其中的每一个索引表项对应了一种空闲分区类型,并记录了该类型空闲分区链表表头的指针
  3. 该算法在搜索可分配的空闲分区时分为两步:
  • 第一步: 根据进程的长度,从索引表中去寻找到能容纳它的最小空闲区链表
  • 第二步: 从链表中取下第一块进行分配即可
  1. 优点: 不会对任何分区产生分割,所以能保留大的分区,也不会产生内存碎片,同时查找效率高
  2. 缺点: 在分区归还主存时的算法复杂,系统开销大。同时因为整个空间给线程,所以或多或少会造成浪费

3.5.2 伙伴系统

  1. 该算法规定,无论是已分配还是未分配的区域,其大小都是2的k次幂(k为整数,1 <= k <= m)
  2. 当需要为进程分配一个长度为n的存储空间时,首先计算一个i值,使 2i-1<n<=2i,然后在空闲分区大小为2i的空闲分区链表中查找
  • 若找到,即把空间分配给该进程
  • 若找不到,说明 2i的空闲分区已经耗尽,则在2i+1中找,详情见分配规则
  1. 伙伴系统中,其分配和回收的时间性能取决于查找空闲分区的位置和分割、合并空闲分区所花费的时间
  2. 时间上,在回收空闲分区时需要对空闲分区合并,其时间性能比快速适应差,比顺序搜索好
  3. 空间上,由于对空闲分区进行合并,提高了空闲分区的可使用率,故优于快速适应算法,比顺序搜索法略差

3.5.2.1 分配规则

  1. 若 2i不存在,则找 2i+1,若有,则把2i+1分成两个2i他们被称为一对伙伴,一个分配给进程,另一个加入2i的分区链表
  2. 若 2i+1也不存在,则需要查找2i+2的空闲分区,若找到则也将其分为一对伙伴,一个做第一步操作,另一个加入2i+1的分区链表
  3. 由此可见,在最坏的情况下,可能需要对 2k的空闲分区进行k次分割才能得到所需分区

3.5.2.2 回收规则

  1. 一次回收也可能要进行多次合并,如回收大小为2i的空闲分区时,若事先已存在2i的空闲分区,则应将其与伙伴分区分并为2i+1的分区
  2. 若事先存在 2i+1的分区,则继续合并为 2i+2的空闲分区,以此类推

3.5.3 哈希算法

  1. 上述的分类搜索算法,都是将空闲分区根据分区大小进行分类,对于每一类具有相同大小的空闲分区,单独设立一个空闲分区链表。在为进程分配空间时,需要在一张管理索引表中查到所需空间大小对应的表项,从中得到对应的空闲分区链表表头指针,从而通过查找得到一个空闲分区
  2. 如果对空闲分区分类较细,则相应索引的表项也就较多,因此会显著的增加搜索索引表的表项的时间开销
  3. 哈希算法:根据所需空闲分区大小,通过哈希函数计算,得到在哈希表中位置,从中得到相应的空闲分区链,实现最佳分配策略

3.6 动态可重定位分区分配

3.6.1 紧凑

  1. 连续分配的一个重要特点是,一个系统或用户程序必须装入一片连续的内存空间中,当计算机运行一段时间后,内存空间将会被分割成许多小的分区,而缺乏大的空闲空间
  2. 紧凑 :将内存中的所有作业进行移动,使他们全都相邻接。
  3. 紧凑带来的问题:经过紧凑后的用户程序在内存中的位置发生了变换,此时若不对程序和数据的地址加以修改,程序会无法执行。为此每次紧凑后都必须对移动了的程序或数据进行重定位,大大影响了效率

3.6.2 动态重定位

  1. 在2.1中所说的动态运行时的装入方式中,作业装入内存后的所有地址仍然都是相对(逻辑)地址。而将相对地址转换为绝对(物理地址)的工作被推迟到程序指令要真正执行时
  2. 为了使地址的转换不会影响到指令的执行速度,必须有硬件地址变换机构的支持,即须在系统中增设一个重定位寄存器,用于存放程序(数据)在内存中的起始地址
  3. 程序在执行时,真正访问的内存地址是相对地址与重定位寄存器中的地址相加而形成的
  4. 此时当系统对内存进行了紧凑,则不需要对程序做任何修改,只需要用该程序在内存的新起始地址去置换原来的起始地址即可

3.6.3 动态重定位分区分配算法

  1. 该算法与**动态分区分配算法(3.3.2)**基本相同,差别仅在于这种算法增加了紧凑的功能
  2. 如果该算法不能找到一个足够大的空间分区以满足用户的需求,如果所有的小的空闲分区的容量总和大于用户的要求,这时便须对内存进行紧凑,将紧凑后的大空间分区分配给用户
  3. 如果所有的小的空闲分区的容量总和仍小于用户的要求,则返回分配失败信息

四. 对换

  1. 由于当时计算机的内存都非常小,为了使该系统能分时运行多个用户程序而引入了对换技术
  2. 系统把所有的用户作业放在磁盘上,每次只能调入一个作业进入内存,当作业的一个时间片用完时,将它调至外存的后备队列上等待,再从后备队列上将另一个作业调入内存。这是最早出现的分时系统中所用的对换技术
  3. 由上可知:要实现内、外存之间的对换,系统中必须有一台I/O速度较高的外存,而且其容量也必须足够大,能容纳正在分时运行的所有用户作业,目前最常使用的是大容量磁盘存储器。下面主要介绍目前在多道程序环境中广泛使用的对换技术

4.1 多道程序环境下的对换技术

4.1.1 对换的概念、引入

  1. 在多道程序下,内存中的某些进程由于某事件尚未发生而被阻塞运行,但它却占用大量的内存空间,甚至有时可能出现在内存中所有进程都被阻塞的情况,此时又有很多作业,因内存空间不足而一直驻留在外存上,显然这对系统资源是一种严重的浪费,且使系统吞吐量下降,为了解决上述问题,系统中又增设了对换(也称交换)设施
  2. 对换: 指把内存中暂时不能运行的进程或者暂时不用的程序和数据换出到外存上,以腾出足够的内存空间,再把已具备运行条件的进程或进程所需要的程序和数据换入内存
  3. 各个UNIX版本实现对换功能的方法也大体上是一样的,即在系统中设置一个对换进程,由它将内存暂时不能运行的进程调出到磁盘的对换区,同样也由该进程将磁盘上已具备运行条件的进程调入内存
  4. 在windows的OS中也具有对换功能,如果一个新进程在装入内存时发现内存不足,可以将已在内存中的老金城调至磁盘,腾出内存空间

4.1.2 对换的类型

  1. 整体对换 :在处理机调度时已经说明,处理机中级调度实际上就是存储器的对换功能,其目的是用来解决内存紧张问题,并可进一步提高内存的利用率和系统的吞吐量。由于在中级调度中对换是以整个进程为单位的,故称为进城对换整体对换。这种对换被广泛应用于多道程序系统中,并作为处理机中级调度
  2. 页面(分段)对换:如果对换是以进程的一个页面或分段为单位进行的,则分别称之为页面对换分段对换,又统称为部分对换。这种方法是实现 请求分页和请求分段式存储管理的基础,其目的是为了支持虚拟存储系统
  3. 此处只讲进程对换,分页或分段对换将在虚拟存储器中介绍,为了实现进程对换,系统必须能实现三方面功能:对对换空间的管理、进程的换出和进程的换入

4.2 对换空间的管理

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

在具有对换功能的OS中,通常把磁盘空间分为文件区和对换区两部分

  1. 对文件区管理的主要目标 :文件区占用磁盘空间的大部分,用于存放各类文件。由于通常的文件都是较长时间的驻留在外存上,对它访问的效率是较低的,故对文件区管理的主要目标是提高文件存储空间的利用率,然后才是提高对文件的访问速度。因此,对文件空间的管理采取离散分配方式
  2. 对对换空间管理的主要目标 :对换空间只占用磁盘空间的小部分,用于存放从内存换出的进程。由于这些进程在对换区中驻留的时间是短暂的,而对换操作的频率较高,故对对换空间管理的主要目标,是提高进程切入和换出的速度,然后才是提高文件存储空间的利用率。因此,对对换区空间的管理采取连续分配方式

4.2.2 对换区空闲盘块管理中的数据结构

  1. 为了实现对对换区中的空闲盘块的管理,在系统中应配置相应的数据结构,用于记录外存对换区中的空闲盘块的使用情况
  2. 其数据结构的形式与内存在动态分区分配方式中所用数据结构相似,及同样可以用空闲分区表或空闲分区链
  3. 在空闲分区表的每个表目中,应包含两项:对换区的首址及其大小,分别用盘块号和盘块数表示

4.2.3 对换空间的分配与回收

由于对换分区的分配采用的是连续分配方式,因而对换空间的分配与回收与动态分区方式时的内存分配与回收方法雷同。,其算法也可以是首次适应算法循环首次适应算法最佳适应算法等,对换区的回收操作可分为四种情况:

  1. 回收分区与插入点的前一个空闲分区F1相邻接
  2. 回收分区与插入点的后一个空闲分区F2相邻接
  3. 回收分区同时与插入点的前、后两个分区邻接
  4. 回收分区既不与F1邻接,又不与F2邻接

4.3 进程的换出与换入

当内核因执行某操作而发现内存不足时,如当一进程由于创建子进程而需要更多的内存空间,但又无足够的内存空间等情况发生时,便调用(或唤醒)对换进程,它的主要任务时实现进程的换出和换入

4.3.1 进程的换出

对换进程在实现进程换出时,是将内存中的某些进程调出至对换区,以便腾出内存空间,换出过程可分为以下两步

  1. 选择被换出的进程:对换进程在选择被换出的进程时,将检查所有驻留在内存中的进程,首先选择处于阻塞状态的进程,当有多个阻塞进程时,应当优先选择优先级最低的进程作为换出进程。
  2. 进程换出的过程:在选择换出进程后,在对进程换出时,只能换出非共享的程序和数据段,而对于那些共享的程序和数据段,只要有进程还需要它,就不能被换出。在进行换出时,应先申请对换空间,若申请成功就启动磁盘,将该进程程序和数据传送到磁盘的对换区上,若传送过程未出现错误,便可回收该进程所占用的内存空间。并对该进程的进程控制块和内存分配表等数据结构做相应的修改。若此时内存还有可换出的进程,则继续执行换出过程,直到内存中再无阻塞进程为止

4.3.2 进程的换入

  1. 对换进程将定时执行换入操作,它首先查看 PCB 集合中所有进程的状态,从中找出“就绪”状态但已换出的进程
  2. 当有许多这样的进程时,它将选择其中已换出到磁盘时间最久(必须大于规定时间,如2s)的进程作为换入进程,为它申请内存。
  3. 如果申请成功,可直接将进程从外存调入内存,如果失败,则需要先将内存中的某些进程换出,腾出足够的内存空间后,再将进程调入
  4. 在对换进程成功的换入一个进程后,若还有可换入的进程,则再继续执行换入换出过程,将其与“就绪且换出”状态的进程陆续换入,知道内存中再无“就绪且换出”状态进程,或者已无足够的内存来换入进程,此时对换进程才停止换入
  5. 由于要交换一个进程需要很多的时间,因此,对于提高处理机的利用率而言,它并不是一个非常有效的解决方法,目前用得较多的对换方案是,在处理及正常运行时,并不启动对换程序,但如果发现有许多进程在运行时进程发生缺页或者内存紧张的情况,才启动对换程序,将一部分进程调至外存。当发现所有进程的缺页率都已明显减少,而系统的吞吐量已下降时,则可暂停运行兑换程序

AA

操作系统 - 存储器管理系统相关推荐

  1. 操作系统——存储器管理

    操作系统--存储器管理 程序的装入和链接 用户程序想要在系统中运行,必须先将他装入内存,然后再将其转变为一个可执行的程序,步骤: 编译-->链接-->装入 程序的装入: 绝对装入方式:(只 ...

  2. 操作系统存储器管理管理试验

    存储器管理 一.目的 本课题实验的目的是,使学生实验存储器管理系统的设计方法:加深对所学各种存储器管理方案的了解:要求采用一些常用的存储器分配算法,设计一个存储器管理模拟系统并调试运行. 二.要求及提 ...

  3. 操作系统-存储器管理实验

    存储器管理 一.目的 本课题实验的目的是,使学生实验存储器管理系统的设计方法:加深对所学各种存储器管理方案的了解:要求采用一些常用的存储器分配算法,设计一个存储器管理模拟系统并调试运行. 二.题目 存 ...

  4. 操作系统——存储器管理的功能

    一. 内容总览 二. 内存空间的分配和回收 为了能将用户程序装入内存,必须为它分配一定大小的内存空间.连续分配方式是最早出现的一种存储器分配方式 该分配方式为一个用户程序分配一个连续的内存空间,即程序 ...

  5. 操作系统存储器管理实验报告_献上膝盖!华为工程师抛出一份堪称“举世无双”操作系统笔记...

    写在前面 操作系统在计算机行业中是一门最基础的技术,无论是在开发项目还是在算法岗,我们都是基于计算机上进行的,我们对操作系统的了解体现我们从事计算机相关岗位的资深素质,因此,接下来,这篇文章给大家介绍 ...

  6. 操作系统—存储器管理

    存储器管理 1 存储器的层次结构 ​ 计算机执行时,几乎每条指令都涉及对存储器的访问.因此要求对存储器的访问速度跟得上处理机的运行速度.考虑到价格和现实因素,如今的计算机大都采用了多层结构的存储器系统 ...

  7. 操作系统——存储器管理(连续分配存储管理方式)

    文章目录 一.单一连续分配 二.固定分区分配 1. 划分分区的方法 2. 内存分配 三.动态分区分配 1. 动态分区分配中的数据结构 2. 动态分区分配算法 3. 分区分配操作 四.基于顺序搜索的动态 ...

  8. 什么是底层架构_厉害!阿里技术专家发布1500多页计算机底层架构原理解析宝典|现代汽车|计算机|原理|操作系统|存储器...

    计算机被称为20世纪最伟大的发明之一 .1946年诞生的第一台电子计算机ENIAC,是一个每秒能运行5000次.重达30吨的庞然大物.如今计算机变得无处不在,以至于人们大大低估了它的复杂性一今天一 部 ...

  9. 模拟存储器管理C语言,操作系统-存储器管理实验C语言.doc

    #include "stdio.h" #include "stdlib.h" #include "string.h" #define Siz ...

最新文章

  1. 教你怎么修改个性开机画面
  2. Swift:如何优雅地使用 print()(三)
  3. JVM调优-GC参数
  4. iOS 开发疑难杂症(01)
  5. SpringSecurity自定义登陆页面和跳转页面
  6. echarts formatter_牛X!用 Echarts 打造一个轮播图!
  7. python rabitmq_python使用rabbitmq实例二,工作队列
  8. AXFR和IXFR区域传输及原理
  9. layui table动态选中_layui后台管理—table 数据表格详细讲解
  10. win10 Anaconda 安装教程
  11. iOS应用架构谈 本地持久化方案及动态部署
  12. nltk——文本分类
  13. libmodbus使用
  14. java数据库连接Druidsql失败_Druid数据库连接池异常connection holder is null
  15. 如何写一个仿真文件——testbench
  16. 电压的降额 Voltage Derating
  17. Manjaro蓝牙连接问题
  18. 昨天搭完梯子之后就打不开12306查询的网页了
  19. 事件委托、事件冒泡与事件捕获
  20. 个人日记-阿西莫夫的《银河帝国》系列小说第8本读后感-20200927

热门文章

  1. 代数一千二百年:花拉子米和智慧宫 ︱ 尼克
  2. 如何把vmware 10变成英文版。。。
  3. 545day(jquery-ajax-event.html)
  4. 如何识别64位和32位CPU
  5. 【Unity 骨骼动画】骨骼IK
  6. python 使用pandas将xlsx转成csv
  7. 3DMAX模型转换为gltf格式总结与问题汇总
  8. background各个属性详解
  9. Android项目源码分享
  10. java被整除的数相加满十,小学数学,一个数能同时被多个数整除怎么判断