操作系统--内存管理

1、内存的基础知识

  • 内存:用于存放数据的硬件

  • 存储单元:内存存储的基本划分单位

  • 按字节编址:每个存储单元的大小是一字节(1B)

  • 按字编址:每个存储单元的大小是一个字(字的大小取决于字长)

  • 物理地址(绝对地址):是当前数据在整个计算机内存中的绝对位置

  • 逻辑地址(相对地址):是指当前数据在本进程之内的偏移量地址

1.1 程序的运行步骤

  1. 编辑源代码文件
  2. 编译:由源代码文件生成目标模块
  3. 链接:由目标模块生成装入模块,链接后形成完整的逻辑地址
  4. 装入:将装入模块装入内存,装入后形成物理地址

1.2 三种链接方式

  • 静态链接:装入前链接成一个完整的装入模块
  • 装入时动态链接:运行前边装入边链接
  • 运行时动态链接:运行时需要的目标模块猜装入并链接

1.3 三种装入方式

  • 绝对装入
  • 可重定位装入
  • 动态运行时装入

1.4 内存管理的内容

  • 内存空间的分配与回收
  • 内存空间的扩充
  • 地址转化
  • 存储保护

2、地址转换

 操作系统负责实现逻辑地址到物理地址的转换,三种方式

  • 绝对装入:编译时将逻辑地址转化为物理地址
  • 可重定位装入(静态重定位):装入时将逻辑地址转换为物理地址
  • 动态运行时装入(动态重定位):运行时将逻辑地址转换为物理地址,需设置重定位寄存器

3、存储保护

​  保证各进程在自己的内存空间内运行,不会越界访问

  • 设置上下限寄存器
  • 利用重定位寄存器、界地址寄存器进行判断

4、内存空间的分配与回收

  • 连续分配管理方式
    • 单一连续分配
    • 固定分区分配
    • 动态分区分配
  • 非连续分配管理方式
    • 基本分页存储管理
    • 基本分段存储管理
    • 段页式存储管理

4.1 连续分配管理方式

 连续分配是指为用户进程分配的必须是一个连续的内存空间.

 外部碎片:没有分配的内存过小,无法分配给进程

 内部碎片:分配给进程的内存无法被全部利用

特点 外部碎片 内部碎片
单一连续分配 只支持单道程序,用户程序放在用户区
固定分区分配 支持多道程序,内存用户空间分为若干大小固定的分区
动态分区分配 支持多道程序,根据进程大小动态地建立分区

(1) 单一连续分配

​  将整个内存空间全部分配给一个用户区

​  无外部碎片但是有大量的内部碎片,并且只能用于单用户单道

​  存储器利用率极低

在这里插入图片描述

(2) 固定分区分配

​  系统将用户空间划分为若干固定大小的区,每一个进程占用一个区.

  • 分区大小相等

    • 缺乏灵活性
    • 但是很适合控制多个相同对象
  • 分区大小不相等

    • 增加了灵活性
    • 常在系统中根据作业的大小分配内存

     无外部碎片

     有大量的内部碎片

在这里插入图片描述

(3) 动态分区分配

​  不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态的建立分区

 两种常用的数据结构:空闲分区表、空闲分区链

​  空闲分区表(链):记录了每一个未被分配的分区(由已分配分区划分而出)的相关信息

​  没有内部碎片,但是有外部碎片,可以通过紧凑技术解决外部碎片

​  回收内存分区时,要合并相邻空闲分区

4.2 动态分区分配算法

算法 思想 空闲分区排列顺序 优点 缺点
首次适应 从头到尾找合适的分区 以地址递增次序排序 综合性能最好,开销小,回收后不需要对空闲分区重新排序
最佳适应 优先使用更小的分区 以空间容量递增次序排列 会有更多的大分区被保留,更能满足大进程需求 会产生很多小碎片,算法开销大,回收分区后需要对空闲分区重新排序
最坏适应 优先使用更大的分区 以空间容量递减次序排列 可以减少难以利用的小碎片 大分区容易被用完,不利于大进程,算法开销大
临近适应 由首次适应演变,每次从上次查找结束的位置开始查找 以地址递增次序排序 不用每次都从低地址的小分区开始检索,开销小 会使高地址的大分区也被用完

4.3 基本分页存储管理

4.3.1 分页基础

(1)概念

​  把内存分为一个个相等的小分区,称为页框,再按照分区大小将用户进程分为若干小分区,成为页面。每一个页面都对应分配一个页框

在这里插入图片描述
​  各个页面不必连续存放,也不必按照先后顺序来,可以放到不相邻的各个页框中.

​  操作系统为每个进程建立一张页表,其中按顺序存储了进程中每一个页对应的页框号(内存中的映射)

(2)地址转换(无页表)

  1. 计算出逻辑地址对应的页号
  2. 找出对应页面在内存的存放位置
  3. 算出逻辑地址对应的页内偏移量
  4. 物理地址=页面起始地址+页面偏移量

(3)页号、页内偏移量的计算

​ 1)人工计算

​  页号=逻辑地址/页面大小

​  页内偏移量=逻辑地址%页面大小

​ 2)根据逻辑地址存储结构

​  分页存储管理的逻辑结构如下所示:

​ 00000000000000000000 000000000001

31 … 12 11 … 0
页号P 页内偏移量W

​  如果有K位表示“页内偏移量”,说明该系统中一个页面的大小使2的k次个内存单元

​  如果有M位表示“页号”,则说明该系统中,一个进程最多允许有2的M次个页面

(3)页表

 操作系统位每个进程建立一张页表,用来确定进程的每个页面在内存中的存放位置

  • 一个进程对应一张页表
  • 进程的每一页对应一个页表项
  • 每个页表项由“页号”和“块号”组成
  • 页面记录页面和实际存放的内存块之间的对应关系
  • 因为每个页表项长度相同,所以页号使“隐含”的

在这里插入图片描述

4.3.2 基本地址变换机构

  1. 根据逻辑地址算出页号、页内偏移量
  2. 页号的合法性检查
  3. 若页号合法,再根据页表起始地址、页号找到对应页表项
  4. 根据页表项中记录的内存块号、页内偏移量得到最后的物理地址
  5. 访问物理内存对应的内存单元

在这里插入图片描述
 细节:

  • 熟悉页内偏移量位数与页面大小的关系
  • 页式管理中地址是一维的
  • 实际应用中,通常使一个页框恰好能放入整数个页表项
  • 为了方便,页表一般使放在连续的内存块中的

4.3.3 快表

​  快表,又称联想寄存器(TLB) ,是一种访问速度比内存快很多的高速缓冲存储器,用来存放当前访问的若干页表项,以加速地址变换的过程。与此对应,内存中的页表常称为慢表。

在这里插入图片描述
 引入快表前后的地址变换机构

  1. 算页号、页内偏移量
  2. 检查页号合法性
  3. 查快表。若命中,即可知道页面存放的内存块号,可直接进行⑤;若未命中则进行④
  4. 查页表,找到页面存放的内存块号,并且将页表项复制到快表中
  5. 根据内存块号与页内偏移量得到物理地址
  6. 访问目标内存单元

如果快表命中则只需有一次访存

4.3.4 两级页表

在这里插入图片描述
 两级页表的地址变换

  1. 按照地址结构将逻辑地址拆分成3部分
  2. 从PCB中读出页目录表始址,根据一级页号查页目录表,找到下一级页表在内存中的存放位置
  3. 根据二级页号查表,找到最终想访问的内存块号
  4. 结合页内偏移量得到物理地址

 细节:

  • 多级页表中,各级页表大小不能超过一个页面
  • N级页表访问一个逻辑地址需要N+1次访存

4.4 基本分段存储管理

4.4.1 分段基础

(1)概念

​  分段就是按照一些逻辑上的意义将内存进行划分,这样一来,每个段的大小是不固定的,与分段类似

(2)段表

  • 段表与页表类似,记录了逻辑段到实际存储地址的映射关系
  • 每个段对应一个段表项,各段表项长度相同
  • 段表项由段号(隐含)、段长、基址组成

在这里插入图片描述

4.4.2 地址变换

  1. 由逻辑地址得到段号、段内地址
  2. 段号与段表寄存器中的段长度比较,检查是否越界
  3. 由段表始址、段号找到对应段表项
  4. 根据段表 中记录的段长,检查段内地址是否越界
  5. 由段表中的"基址+段内地址"得到最终的物理地址
  6. 访问目标单元

在这里插入图片描述

4.4.3 分页与分段管理对比

  • 分页对用户不可见,分段对用户可见
  • 分页的地址空间是一维的,分段的地址空间是二维的
  • 分段更容易实现信息的共享和保护(纯代码/可重入代码可以共享)
  • 分页(单级页表)、分段访问-个逻辑地址都需要两次访存,分段存储中也可以引入快表机构

4.5 段页式管理方式

​  利用分段式管理来管理页表,然后通过分页式管理来管理页.这样使用段表将页进行逻辑上的划分,也能实现易于共享的需求了.

​  这里的段表存放的就不是基址了,而是页表长度和页表存放块号

在这里插入图片描述

4.5.1 段表、页表结合

​ 每个段对应一个段表项。各段表项长度相同,由段号(隐含)、页表长度、页表存放地址组成

​ 每个页对应一个页表项。各页表项长度相同,由页号(隐含)、页面存放的内存块号组成
在这里插入图片描述

4.5.2 地址变换

  1. 由逻辑地址得到段号、页号、页内偏移量
  2. 段号与段表寄存器中的段长度比较,检查是否越界
  3. 由段表始址、段号找到对应段表项
  4. 根据段表中记录的页表长度,检查页号是否越界
  5. 由段表中的页表地址、页号得到查询页表,找到相应页表项
  6. 由页面存放的内存块号、页内偏移量得到最终的物理地址
  7. 访问目标单元

在这里插入图片描述

5、内存空间的扩充

  • 覆盖技术
  • 交换技术
  • 虚拟存储技术

5.1 覆盖技术

​  覆盖技术是指将程序分为多个段,使用的那一部分调入内存,不使用的部分在需要时才会调入内存.

​  常驻内存的段放在固定区中,调入后不在调出。不常住的段放在覆盖区,需要时调入,采取覆盖策略

​  程序员必须显式声明覆盖结构
在这里插入图片描述

5.2 交换技术

​ 当内存空间紧张时,将内存中某些进程暂时调出外存,把外存中某些已经具备运行条件的进程调入内存(内存和磁盘中动态调度)

​ 中级调度就是判断哪一些进程适应给被调入的,暂时换出外存等待的进程状态被称为挂起态.

​ 对应于此,磁盘空间也被分为对换区和文件区.对换区追求文件换入换出速度,采用连续分配方式.文件区追求空间的利用率,采用离散分配方式

在这里插入图片描述
注:PCB会常驻内存,不会被换出外存

​  覆盖与交换的区别:覆盖是在一个进程中的,交换是对不同进程的

5.3 虚拟存储技术

​  程序不需全部装入即可运行,运行时根据需要动态调入数据,若内存不够,还需换出一些数据

5.3.1 局部性原理

  • 时间局部性:现在访问的指令、数据在不久后很可能会被再次访问
  • 空间局部性:现在访问的内存单元周围的内存空间,很可能在不久后会被访问
  • 高速缓存技术:使用频繁的数据放到更高速的存储器中

5.3.2 特征

  • 多次性:无需在作业运行时一次性全部装入内存,而是允许被分成多次调入内存。
  • 对换性:无需在作业运行时-直常驻内存,而是允许在作业运行过程中,将作业换入、换出。
  • 虚拟性:从逻辑.上扩充了内存的容量,使用户看到的内存容量,远大于实际的容量。

5.3.3 传统VS虚拟

​  虚拟内存技术,允许-一个作业分多次调入内存。如果采用连续分配方式,会不方便实现。因此,虚拟内存的实现需要建立在离散分配的内存管理方式基础上。.

传统的非连续分配存储管理 虚拟内存的实现
基本分页存储管理 请求分页存储管理
基本分段存储管理 请求分段存储管理
基本段页式存储管理 请求段页式存储管理

区别:

  • 请求调页功能:访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存
  • 页面置换功能:内存空间不够时,将内存中暂时用不到的信息换出到外存

5.3.4 请求分页存储管理

(1)页表的区别

​ 在基本分页的基础上增加了几个表项

  • 状态位:表示页面是否已在内存中
  • 访问字段:记录最近被访问过几次,或记录上次访问的时间,供置换算法选择换出页面时参考
  • 修改位:表示页面调入内存后是否被修改过,只有修改过的页面才需在置换时写回外存
  • 外存地址:页面在外存中存放的位置

(2)缺页中断机构

  • 找到页表项后检查页面是否已在内存,若没在内存,产生缺页中断
  • 缺页中断处理中,需要将目标页面调入内存,有必要时还要换出页面
  • 缺页中断属于内中断,属于内中断中的"故障",即可能被系统修复的异常
  • 一条指令在执行过程中可能产生多次缺页中断

(3)地址变换的区别

  • 找到页表项是需要检查页面是否在内存中
  • 若页面不再内存中,需要请求调页
  • 若内存空间不够,还需换出页面
  • 页面调入内存后,需要修改相应页表项

5.3.5 页面置换算法

算法 算法规则 优缺点
最佳置换算法(OPT) 优先淘汰最长时间内不会被访问的页面 缺页率最小,性能最好;但无法实现
先进先出置换算法(FIFO) 优先淘汰最先进入内存的页面 实现简单;但性能很差,可能出现Belady异常
最近最久未使用置换算法(LRU) 优先淘汰最近最久没访问的页面 性能很好;但需要硬件支持,算法开销大但未考虑页面是否被修改过。
时钟置换算法(CLOCK) 循环扫描各页面,第一轮淘汰访问位=0的,并将扫描过的页面访问,位改为1。若第一轮没选中,则进行第二轮扫描。 实现简单,算法开销小;
改进的时钟置换算法 用(访问位,修改位)的来确定置换 算法开销较小,性能也不错

5.3.6 页面置换策略

 驻留集:指请求分页存储管理中给进程分配的内存块的集合

 工作集:在某段时间间隔里,进程实际访问页面的集合。驻留集大小一般不能小于工作集大小

 抖动(颠簸)现象:页面频繁换入换出的现象。主要原因是分配给进程的物理块不够

(1)页面分配、置换策略

 固定分配VS可变分配:区别在于进程运行期间驻留集大小是否可变

 局部置换VS全局置换:区别在于发生缺页时是否只能从进程自己的页面中选择一个换出

  • 固定分配局部置换:进程运行前就分配一定数量物理块,缺页时只能换出进程自己的某一页
  • 可变分配全局置换:只要缺页就分配新物理块,可能来自空闲物理块,也可能需换出别的进程页面
  • 可变分配局部置换:频繁缺页的进程,多分配一些物理块;缺页率很低的进程,回收一些物理块。直到缺页率合适

(2)何时调页

  • 预调页策略:一般用于进程运行前
  • 请求调页策略:进程运行时,发现缺页再调页

(3)何处调页

​  对换区一采用连续存储方式,速度更快

​  文件区一采用离散存储方式,速度更慢

  • 对换区足够大:运行将数据从文件区复制到对换区,之后所有的页面调入、调出都是在内存与对换区之间进行
  • 对换区不够大:不会修改的数据每次都从文件区调入;会修改的数据调出到对换区,需要时再从对换区调入
发布了119 篇原创文章 · 获赞 45 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_41596568/article/details/104024244