页式内存管理
在操作系统中,页式内存管理是非常重要的内容,页式内存管理,引出了多任务程序设计的基础。
段式内存管理回顾
我们知道计算机上电之后,会实模式跳转到保护模式的。那么这个保护模式,是保护什么的?
这里的保护模式是保护内存段的,在X86处理器中内置的保护模式,一旦保护模式打开,那么某一段内存的访问就是受限的,这里的受限就是指受保护的。保护模式就是来保护一段连续的内存空间,这里的一段连续的内存空间,我们简称为段。
这里的"段"具体指什么?
一段连续的内存空间。
为什么会有段式内存管理
- 程序的各个部分相对独立(如:数据段,代码段),代码段在运行的过程中会访问数据段,但是代码段和数据段时独立的。
- 早期X86处理器无法通过一个寄存器访问所有的内存单元
- 解决早期程序运行时的重定位问题
段式内存管理的应用
- 在X86系列处理器中,硬件对段式内存管理进行了直接支持。
- 另外,段式内存管理也可以使用纯软件实现。
- 核心:段首地址+段内偏移地址 = 内存单元地址
段式内存管理在C语言中的体现
- 数组的本质:一片连续的内存(段)
- 数组名(array):数组的起始内存地址(段地址)
- 数组元素的访问:array[i] <--> *(array + i)
- 第i个元素的地址:array(段地址) + i(偏移地址)
操作系统中只使用段式内存管理是否足够?
软件硬件技术发展
硬件技术
- 计算机部件独立化(硬件接口相同,可以任意组装)
- 计算机配置差异化(各个部件硬件参数不同,如:内存容量)
软件技术
- 应用程序出来的问题越来越复杂(解决实际问题)
- 应用程序运行需要的资源越来越多(物理内存可能无法满足,所以就诞生了虚拟内存管理)
问题
应用程序规模越来越大,导致多数时候无法全部加载进内存,如何解决?
可行解决方案:按段加载(局部性原理)
- 不管应用程序规模多大,在某个很短的时间范围内存,程序总是在某个局部运行。
- 只将当前程序运行需要的段加载进内存。
- 当某个段不再需要使用,立即从内存中移除。
按断加载可能带来的问题
- 段的大小不确定,某些应用程序很复杂,可能一个段的大小就会大于实际的物理内存。有可能程序中的某一个局部的内存段就会大于实际的物理内存,那么这个局部的内存段就没有办法加载到内存中去,那么这个程序就没有办法运行了。
- 段加载时需要具体的长度信息,导致效率不高。
有更进一步的解决方案是,在段的基础上,进行分页。
更进一步的解决方案:内存分页
- 页指的是固定大小的内存片(4KB)
- 每一个内存段由多个页组成
- 页是进行内存管理的基本单位(加载页,换出页)
应用程序数据段、代码段、堆栈段 是相对独立的。
每个段都是有各个页组成的
代码段在运行过程中,会去加载数据段的内容,也会去加载堆栈段的内容。
生活中“段页式”应用
大多数情况下,书都采用“段页式”的方法进行内容编排。
书是由一章一章组成的,一章一章不固定,然后一章一章是由页组成的。
章的大小不固定,就相当于程序中的段,页的大小固定,相当于程序中的页。
进阶虚拟存储技术
- 实模式下所使用的是什么地址空间?物理地址空间
- 保护模式下所使用的是什么地址空间?偏移地址(线性地址)空间,保护模式下,都是由段地址 + 段内偏移地址 组成的
- 如何分离不同应用程序所使用的内存空间?提前分页规划好
- 程序运行需要的内存大于实际物理内存该怎么办?分页,按页加载
内存分页的意义
虚拟内存空间(逻辑地址):程序执行时内部所使用的内存空间(独立于其他程序)
物理内存空间(物理地址):物理机器所配置的实际内存空间(所有程序共享)
虚拟地址(逻辑地址)需要进行转换(内存映射)才能得到对应的物理地址。
这个转换(内存映射)是怎么进行的?
页式内存管理中的地址
地址 = 页号 + 页内偏移
- 逻辑地址(虚拟地址) = 逻辑页号(虚拟页号) + 页内偏移
- 物理地址 = 物理页号 + 页内偏移
- 地址转换时仅仅变更页号即可,页内偏移不变
逻辑地址(虚拟地址)到物理地址的映射(重定位)
0XAABBCC12(逻辑地址) --> MMU --> 0xDDCC12(物理地址)
MMU会去查询地址映射表(页表)
逻辑页号 | 物理页号 | 属性 |
..... | ...... | ...... |
0XAABB | 0XDD | 0X00 |
...... | ...... | ..... |
0XAABBCC12(虚拟地址) 到 MMU中去查表,发现逻辑页号 0XAABB 存在页表中,然后对应的物理页号是0XDD,所以把虚拟地址的高位AABB 替换成 DD,低位不变。所以最后的物理地址就是:0XDDCC12
页式内存管理中的关键操作一
页请求
访问一个逻辑地址(虚拟地址)时,对应的页不在内存中
- 从外存中将目标页加到内存中
- 之后更新页表
页式内存管理中的关键操作二
页交换
页请求时发现物理内存不足,需要将暂时不用的页移除
- 首先,决定并选择需要移除的页
- 将选中页中的所有数据写入外存
- 更新页表,重新进行页请求
小结
- 内存分段能够解决一定的问题,但无法保证程序的移植行
- 根据程序运行的局部性原理,可进一步对内存进行分页
- 页指的是固定大小的内存片(4KB) (1MB)
- 页的引入使得程序的逻辑地址与内存的物理地址彻底分离
- 操作系统的内存管理是以页为单位完成的
页式内存管理需要注意的问题
- 操作系统如何管理实际的物理内存?
- 页表与不同任务(app)有怎么样的关系?每个任务都有自己专属的页表,当任务结束之后,这个页表就摧毁了。
- 页表对于任务(app)的意义是什么?
- 页交换时如何选择需要替换的内存页?
- 页表具体是如何构成的?
操作系统如何管理实际的物理内存?
页框与页面(Frame and Page)
- 页框(Frame) :物理内存空间中的页(物理页)
- 页面(Page) :逻辑内存空间中的页(逻辑页)
- 页框(Frame)用于存储页面(Page)内容,而页面内容来源于逻辑内存(虚拟内存)空间。
操作系统必须知道物理内存的使用情况
- 建立结构(数据结构)对物理内存进行管理(Frame Table)
- 结构记录:页框是否可用,被谁使用,等
- 为具体的应用程序分配页表
//未完待续.....