> 文章列表 > 页式内存管理

页式内存管理

页式内存管理

在操作系统中,页式内存管理是非常重要的内容,页式内存管理,引出了多任务程序设计的基础。

段式内存管理回顾

我们知道计算机上电之后,会实模式跳转到保护模式的。那么这个保护模式,是保护什么的?

这里的保护模式是保护内存段的,在X86处理器中内置的保护模式,一旦保护模式打开,那么某一段内存的访问就是受限的,这里的受限就是指受保护的。保护模式就是来保护一段连续的内存空间,这里的一段连续的内存空间,我们简称为段。

这里的"段"具体指什么?

一段连续的内存空间。

为什么会有段式内存管理

  1. 程序的各个部分相对独立(如:数据段,代码段),代码段在运行的过程中会访问数据段,但是代码段和数据段时独立的。
  2. 早期X86处理器无法通过一个寄存器访问所有的内存单元
  3. 解决早期程序运行时的重定位问题

段式内存管理的应用

  1. 在X86系列处理器中,硬件对段式内存管理进行了直接支持。
  2. 另外,段式内存管理也可以使用纯软件实现。
  3. 核心:段首地址+段内偏移地址 = 内存单元地址

段式内存管理在C语言中的体现

  1. 数组的本质:一片连续的内存(段)
  2. 数组名(array):数组的起始内存地址(段地址)
  3. 数组元素的访问:array[i]  <--> *(array + i)
  4. 第i个元素的地址:array(段地址) + i(偏移地址)

操作系统中只使用段式内存管理是否足够?

软件硬件技术发展

硬件技术

  1. 计算机部件独立化(硬件接口相同,可以任意组装)
  2. 计算机配置差异化(各个部件硬件参数不同,如:内存容量)

软件技术

  1. 应用程序出来的问题越来越复杂(解决实际问题)
  2. 应用程序运行需要的资源越来越多(物理内存可能无法满足,所以就诞生了虚拟内存管理)

问题

应用程序规模越来越大,导致多数时候无法全部加载进内存,如何解决?

可行解决方案:按段加载(局部性原理)

  1. 不管应用程序规模多大,在某个很短的时间范围内存,程序总是在某个局部运行。
  2. 只将当前程序运行需要的段加载进内存。
  3. 当某个段不再需要使用,立即从内存中移除。

按断加载可能带来的问题

  1. 段的大小不确定,某些应用程序很复杂,可能一个段的大小就会大于实际的物理内存。有可能程序中的某一个局部的内存段就会大于实际的物理内存,那么这个局部的内存段就没有办法加载到内存中去,那么这个程序就没有办法运行了。
  2. 段加载时需要具体的长度信息,导致效率不高。

有更进一步的解决方案是,在段的基础上,进行分页。

更进一步的解决方案:内存分页

  1. 页指的是固定大小的内存片(4KB)
  2. 每一个内存段由多个页组成
  3. 页是进行内存管理的基本单位(加载页,换出页)

应用程序数据段、代码段、堆栈段 是相对独立的。

每个段都是有各个页组成的

代码段在运行过程中,会去加载数据段的内容,也会去加载堆栈段的内容。

生活中“段页式”应用

大多数情况下,书都采用“段页式”的方法进行内容编排。

书是由一章一章组成的,一章一章不固定,然后一章一章是由页组成的。

章的大小不固定,就相当于程序中的段,页的大小固定,相当于程序中的页。

进阶虚拟存储技术

  1. 实模式下所使用的是什么地址空间?物理地址空间
  2. 保护模式下所使用的是什么地址空间?偏移地址(线性地址)空间,保护模式下,都是由段地址 + 段内偏移地址 组成的
  3. 如何分离不同应用程序所使用的内存空间?提前分页规划好
  4. 程序运行需要的内存大于实际物理内存该怎么办?分页,按页加载

内存分页的意义

虚拟内存空间(逻辑地址):程序执行时内部所使用的内存空间(独立于其他程序)

物理内存空间(物理地址):物理机器所配置的实际内存空间(所有程序共享)

虚拟地址(逻辑地址)需要进行转换(内存映射)才能得到对应的物理地址。

这个转换(内存映射)是怎么进行的?

页式内存管理中的地址

地址 = 页号 + 页内偏移

  1. 逻辑地址(虚拟地址) = 逻辑页号(虚拟页号) + 页内偏移
  2. 物理地址 = 物理页号 + 页内偏移
  3. 地址转换时仅仅变更页号即可,页内偏移不变

逻辑地址(虚拟地址)到物理地址的映射(重定位)

0XAABBCC12(逻辑地址)  --> MMU --> 0xDDCC12(物理地址)

                                               MMU会去查询地址映射表(页表)

逻辑页号 物理页号 属性
..... ...... ......
0XAABB 0XDD 0X00
...... ...... .....

0XAABBCC12(虚拟地址) 到 MMU中去查表,发现逻辑页号 0XAABB 存在页表中,然后对应的物理页号是0XDD,所以把虚拟地址的高位AABB 替换成 DD,低位不变。所以最后的物理地址就是:0XDDCC12

页式内存管理中的关键操作一

页请求

访问一个逻辑地址(虚拟地址)时,对应的页不在内存中

  1. 从外存中将目标页加到内存中
  2. 之后更新页表

页式内存管理中的关键操作二

页交换

页请求时发现物理内存不足,需要将暂时不用的页移除

  1. 首先,决定并选择需要移除的页
  2. 将选中页中的所有数据写入外存
  3. 更新页表,重新进行页请求

小结

  1. 内存分段能够解决一定的问题,但无法保证程序的移植行
  2. 根据程序运行的局部性原理,可进一步对内存进行分页
  3. 页指的是固定大小的内存片(4KB) (1MB)
  4. 页的引入使得程序的逻辑地址与内存的物理地址彻底分离
  5. 操作系统的内存管理是以页为单位完成的

页式内存管理需要注意的问题

  1. 操作系统如何管理实际的物理内存?
  2. 页表与不同任务(app)有怎么样的关系?每个任务都有自己专属的页表,当任务结束之后,这个页表就摧毁了。
  3. 页表对于任务(app)的意义是什么?
  4. 页交换时如何选择需要替换的内存页?
  5. 页表具体是如何构成的?

操作系统如何管理实际的物理内存?

页框与页面(Frame and Page)

  1. 页框(Frame) :物理内存空间中的页(物理页)
  2. 页面(Page) :逻辑内存空间中的页(逻辑页)
  3. 页框(Frame)用于存储页面(Page)内容,而页面内容来源于逻辑内存(虚拟内存)空间。

操作系统必须知道物理内存的使用情况

  1. 建立结构(数据结构)对物理内存进行管理(Frame Table)
  2. 结构记录:页框是否可用,被谁使用,等
  3. 为具体的应用程序分配页表

//未完待续.....