操作系统笔记五-内存管理

2021/12/9 7:24:08

本文主要是介绍操作系统笔记五-内存管理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

概念 

        因为不可能将所有用户进程和系统所需要的全部程序和数据放入主存,操作系统需要对内存空间进行合理的划分和有效的动态分配。操作系统对内存的划分和动态分配称为内存管理。

内存管理的功能

  1. 内存空间的分配与回收。
  2. 地址转换。在多道程序环境下,程序的逻辑地址和内存中的物理地址不一致,需要进行地址转换,将逻辑地址转换为对应的物理地址。
  3. 内存空间的扩充。
  4. 存储保护。

程序装入和链接

        创建进程需要将程序和数据装入内存。用户源程序变为可在内存中执行的程序,通常需要进行编译,链接,装入三个步骤。

  1. 编译。将用户源程序编译成若干个目标模块。
  2. 链接。将目标模块及需要的库函数链接在一起,形成一个装入模块。程序的链接有三种方式。
    1. 静态链接。在程序运行前就将目标模块等链接成装入模块,以后不再拆开。
    2. 装入时动态链接。在装入内存时,边装入边链接。
    3. 运行时动态链接。某些目标模块的链接是在程序执行过程才进行的,优点是便于修改和更新。
  3. 将链接成的装入模块装入到内存中,也有三种方式。
    1. 绝对装入。在编译时知道程序放入内存的地址,编译程序产生绝对地址的目标代码。绝对装入程序按照装入模块中的地址将程序和数据装入内存。程序中的逻辑地址与实际内存地址完全相同。只适用于单道程序环境。
    2. 可重定位装入。在将装入模块装入到内存中时将装入模块的逻辑地址转换为物理地址的过程称为重定位,地址变换是在装入时一次完成的,所以又称静态重定位。
    3. 动态运行时装入(动态重定位)。在装入模块装入时并不立即进行地址的转换,而是将地址转换推迟到程序真正要执行时才进行。装入到内存中的地址称为相对地址,需要一个重定位寄存器进行地址转换。可以将程序分配到不连续的存储区,只要装入部分代码即可投入运行。

逻辑地址和物理地址

  1. 编译后目标模块都从0号单元开始编址,称为目标模块的相对地址(逻辑地址)。目标模块链接后形成一个装入模块,按链接顺序构成一个从0号单元开始编址的逻辑地址空间。
  2. 物理地址空间指内存中物理单元的集合。进程在运行时执行指令和访问数据都需要通过物理地址从主存中存取。地址转换将逻辑地址转换成物理地址。

内存保护

  1. 设置一对上、下限寄存器,存放在主存中的上下限地址,当cpu访问地址时,通过和两个寄存器值对比判断是否越界。
  2. 采用重定位寄存器(基址寄存器)和界地址寄存器(限长寄存器)。

 内存空间的扩充

  1. 覆盖。将用户空间分为固定区和若干覆盖区,经常活跃的部分放在固定区,其余部分按调用关系分段。在需要调用存放在外存中的段时,将其调入覆盖区,覆盖原有的段。覆盖需要知道程序段之间的覆盖结构。
  2. 交换。将处于等待状态的程序从内存移到辅存,称为换出;将准备好竞争cpu运行的程序从辅存移到内存,称为换入。磁盘分为文件区和对换区,换出的进程放在对换区。

连续分配管理方式

  1. 单一连续分配。内存在此方式下分为系统区和用户区,系统区仅供操作系统使用,通常在低地址部分;用户区供用户使用。简单,只能用于单用户,单任务的操作系统,无外部碎片,有内部碎片。
  2. 固定分区分配。将用户内存空间划分为若干固定大小的区域,每个分区只装入一道作业。当作业太大无法放入一个分区时,不得不使用覆盖技术来使用内存空间。当作业太小,会造成空间浪费,出现内部碎片。无外部碎片。
  3. 动态分区分配。不预先划分内存,在进程装入内存时,根据进程的大小动态地建立分区,使分区的大小正好适合进程的需要。无内部碎片,有外部碎片。
    1. 首次适应算法。空闲分区按地址递增的次序链接。分配内存时顺序查找,找到第一个大小能满足要求的第一个空闲分区。
    2. 最佳适应算法。空闲分区按容量递增的方式形成分区链,找到第一个满足要求的空闲分区。
    3. 最坏适应算法。空闲分区按容量递减的方式形成分区链,找到第一个满足要求的空闲分区。
    4. 临近适应算法。与首次适应算法相似,区别是从上次查找结束的位置开始继续查找。

非连续分配管理方式

        非连续分配允许一个程序分散地装入不相邻的内存分区。需要知道分散在内存的哪些区域,所以需要额外的空间存储索引。

        根据分区大小是否固定可分为:分页存储管理方式和分段存储管理方式。

        分页存储管理方式根据运行作业时是否要把作业的所有页面装入内存才能运行分为基本分页存储管理方式和请求分页存储管理方式。

  1. 基本分页存储管理方式
    1. 为什么要分页? 固定分区分配会产生内部碎片,动态分区分配会产生外部碎片,为了解决碎片问题,所以引入了分页的思想。
    2. 将主存空间分为大小相等固定的块,块相对较小,一般每页4KB,称为页框或页帧。不会产生外部碎片。
    3. 进程也按块划分,称为页。在执行时以页为单位申请主存中的块空间,页和页框产生一一对应的关系。只有在为最后的页申请主存空间时才可能产生内部碎片,但内部碎片相对进程来说很小。
    4. 为了方便地址转换,页面大小是2的整数幂。32位地址长度,每页大小4KB,则低12位为页内偏移量,12-31位为页号。
    5. 页表。因为将进程分散地装入内存中,所以需要为每个进程创建一张页表,找到进程页面对应的物理块。页表由页表项组成,页表项第一部分是页号,第二部分是物理块号。
    6. 基本地址变换机构。将逻辑地址转换为内存中的物理地址。借助页表实现。设置一个页表寄存器,存放的是页表起始地址和页表长度。
      1. 根据逻辑地址跟页面大小可以计算出页号与页内偏移量。给出的条件值为十进制数,页号 = 逻辑地址 / 页面大小,页内偏移量 = 逻辑地址 % 页面大小。二进制数,32位地址长度,每页大小4KB,则低12位为页内偏移量,12-31位为页号。
      2. 比较页号跟页表长度判断是否越界。
      3. 页表中页号P对应的页表项地址 = 页表始址 + 页号 * 页表项长度,找到对应的页表项就能得到对应的物理块号。
      4. 区分页表长度跟页表项长度:页表长度指的是页的数量,页表项长度指的是页地址占的存储空间。
      5. 物理地址 = 物理块号 * 页面大小 + 页内偏移量。
    7. 具有快表的地址变换机构。页表存储在内存中,存取数据或指令需要两次访存,一次是查页表,一次是查内存。引入快表用于存放当前访问的若干页表项,以加速地址变换的过程。快表是一个高速缓冲存储器,若在快表中找到对应的页表项,则只需要一次访存。快表的有效性基于局部性原理。
    8. 两级页表。当页表过大时,需要在主存中找到一块较大的连续内存空间进行存储。为了压缩页表,根据页表映射的思想,就是根据前面提到的固定分区分配和动态分区分配的弊端,采用非连续分配管理方式,使用页表保存映射关系。类似的,可以将页表也分散建立映射关系,得到二级页表,根据一级页表可以查找到二级页表的位置。类似的可以有多级页表。规定顶级页表只能有1个页面。多级页表的弊端就是需要多次访存。
  2. 基本分段存储管理方式
    1. 分段。段式管理方式按照用户进程中的自然段划分逻辑空间。在段式系统中,段号和段内偏移量必须由用户显式提供。
    2. 段表。每个进程都有一张逻辑空间与内存空间映射的段表,实现从逻辑段到物理内存的映射。段表项记录由段号,段长,本段在主存的始址组成。
    3. 地址变换机构。
      1. 设置段表寄存器,存放段表的起始地址和段表长度。与分页存储管理方式类似,逻辑地址前几位为段号,后几位为段内偏移量。
      2. 段号与段表长度比较判断是否发生越界。
      3. 段号S对应的段表项地址 = 段表始址 + 段号 * 段表项长度
      4. 根据段表项地址取出本段在主存中的始址,物理地址 = 始址 + 段内偏移量。
    4. 段的共享。通过两个作业的段表中相应表项指向被共享的段的同一物理副本来实现的。
    5. 段的保护。
      1. 存取控制保护。
      2. 地址越界保护。(1)段号 > 段表长度,发生越界。段表长度指的是有多少个段表项(2)段内偏移量 > 段长,发生越界。因为段式管理的每段长度是不固定的,所以需要判断是否越界。
  3. 段页式存储管理方式
    1. 页式存储管理能有效提高内存利用率,分段存储管理有利于段的共享,结合两种方法便形成段页式存储管理方式。
    2. 先将作业的地址空间分为若干逻辑段,再将每段分成若干大小固定的页。对内存空间的管理与分页存储管理一样,将其分成若干和页面大小相同的存储块。
    3. 作业的逻辑地址组成:段号、页号和页内偏移量。
    4. 地址转换。每个进程都有一张段表,每个分段有一张页表。段表表项至少包括段号,页表长度和页表始址;页表表项至少包括页号和块号。还需要一个段表寄存器。

 



这篇关于操作系统笔记五-内存管理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程