文章目录
一、页式存储
1、CPU 调用数据
存储系统 中 , 操作系统 会将 外存 ( 磁盘 ) 中的数据 , 调入 内存 ( 内存条 ) 中 , 内存中的数据 再 给 CPU 调用 , CPU 中有涉及到 三级高速缓存 和 寄存器 的数据传递 ;
如果 CPU 调用的 数据 不在 内存中 , 此时 CPU 会产生 " 缺页中断 " , 从 外存 调数据 到 内存 中 , 内存数据 就绪后 返回到 中断位置 继续执行 ;
2、内存存储数据弊端
如果磁盘中的文件有 50G , 内存只有 16G , 显然 内存 中只能存放 部分 磁盘数据 , 此外 内存 中的 可用空间 也不一定是连续的 ;
- 内存的 可用空间 不一定够用 ;
- 内存的 可用空间 的 地址不一定是连续的 ;
外存中的数据 , 要 先将数据进行切割 , 然后 在 内存 中 分散放置 切割后的数据 ;
切割方式 不同 , 内存 中 的 数据 的 存储调用 方式 也是 不同的 , 根据切割方式 , 内存的存储方式分为 :
- 页式存储
- 段式存储
3、分页存储
分页存储 , 又称为 页式存储 , 将 用户程序的逻辑地址空间 与 物理内存空间 划分成 相同大小的 块 , 一般是 4KB 或 8KB , 这个区域 称为 " 页 " ;
该 分页 机制 , 避免了 连续分配内存 造成的 碎片问题 , 每个 " 内存页数据 “ 可以 单独映射 到不同的 ” 用户程序 逻辑地址空间 中的 物理页框 " 中 ;
" 用户程序 中的 页 “ 与 ” 物理内存 中的 页 “ , 需要通过 ” 页表 " 对应起来 , 页面中 最基础的内容如下 :
- 页号 : 用户程序 中的 页号 , 又称为 " 逻辑页号 " , 用户程序中的地址 称为 逻辑地址 ;
- 块号 : 物理内存 中的 块号 , 又称为 " 页帧号 " , 物理内存中的地址 称为 物理地址 ;
4、逻辑地址 和 物理地址 的结构
" 用户程序 " 中 查询 内存中的数据 , 程序 中 已知 数据的 " 逻辑地址 " 由 CPU 生成 , 根据 逻辑地址 查询该地址在 哪个 " 内存页 " , 然后再 到 " 页表 " 中 查询 该内存页 " 页号 " 对应的 " 块号 " , 然后到 内存块 中查询 内存块 对应的 " 物理地址 " ;
- 逻辑地址 由两部分组成 : 页号 + 页内地址 ;
- 页号 : 表示 逻辑地址空间中的具体页 ;
- 页内地址 : 表示页内的具体位置 , 又称为 " 页内偏移 " ;
- 物理地址 由两部分组成 : 块号 + 页内地址 ;
- 块号 : 表示 物理地址空间中的具体块 , 又称为 " 页帧号 " 或 " 页框号 " ;
- 页内地址 : 表示页内的具体位置 , 又称为 " 页内偏移 " ;
逻辑地址 / 物理地址 分为高位 和 低位 , 高位是 页号 或 块号 , 低位是 业内地址 ;
数据 的 逻辑地址 与 物理地址 , 页内地址 是不变的 , 变化的只是前面的 页号 或 块号 , 逻辑地址 高位是 页号 , 物理地址 高位 是 物理内存 的 块号 ;
5、逻辑地址 和 物理地址 的结构 示例
假设 页大小 为 4KB = 4096 Byte , 也就是 2 12 = 4096 2^{12} = 4096 212=4096 字节 ;
4096 个 存储单元 ( Byte ) 如果使用二进制表示 , 需要 使用 0 ~ 4095 闭区间来表示 ;
4095 对应的二进制数字 就是 0b 1111 1111 1111 , 该二进制数字是 12 个 1 ;
4096 个存储单元的取值范围是 0b 0000 0000 0000 ~ 0b 1111 1111 1111 ;
页内地址 / 页内偏移 必须要 12 位 二进制数 才能 表示 ,
如果 页大小是 8KB , 则需要 13 位 二进制数 才能 作为该页的 页内地址 / 页内偏移 ;
给定 4KB 的页大小 的 逻辑地址 , 低位 12 位是其 页内地址 或 页内偏移 , 高位就是 页号 ;
给定一个逻辑地址 , 计算 物理地址 : 页大小 4 KB , 逻辑地址 为 0b 10 1100 1101 1110 , 参考下面的页表 , 计算出其物理地址 ;
逻辑地址 是 0b 10 1100 1101 1110 ,
- 低 12 位是 0b 1100 1101 1110 , 这是 页内地址 / 页内偏移
- 高 2 位 是 0b 10 , 这是页号 , 对应十进制数为 2 , 参考页表 , 页号为 2 的 内存页 对应 块号 为 6 ;
则 物理地址 的高位是 0b 110 , 低位是页内地址 0b 1100 1101 1110 , 拼接物理地址为 0b 110 1100 1101 1110 ;
6、页式存储 优缺点
页式存储 优缺点 :
- 优点 :
- 缺点 :
- 系统开销大 : 内存页小 , 太过于零碎 , 导致 操作系统每次都需要查表 根据 页号 找 块号 , 造成很多系统开销 ;
- 性能抖动 : 内存调度 时 , 可能产生 性能抖动的现象 , 如 : 由于 系统开销问题 导致 的 分配更多的内存导致系统性能下降的情况 ;
下面的表格中 整理的 页式存储 优缺点 更加全面 :
方面 | 优点 | 缺点 |
---|---|---|
内存利用率 | 减少外部碎片,提高内存利用率 | 可能导致内部碎片 |
管理复杂度 | 简化内存分配和回收 | 页表和多级页表增加了复杂性 |
虚拟内存 | 支持虚拟内存,运行比物理内存更大的程序 | 页面置换引入 I/O 开销 |
内存保护 | 提供内存保护和进程隔离 | 需要额外的硬件和软件支持 |
多任务并发 | 支持多任务并发运行 | 页表切换可能引入额外开销 |
硬件支持 | 现代硬件(如 MMU、TLB)提供高效支持 | TLB 未命中时性能下降 |
地址分配 | 进程地址空间可以非连续存放 | 地址转换开销大,依赖 TLB 加速 |
共享机制 | 方便进程共享内存,减少重复存储 | 共享页可能导致数据同步问题 |
二、逻辑地址 与 物理地址
1、逻辑地址
逻辑地址 定义 : 逻辑地址是 由 应用程序 生成的地址 , 也称为 " 虚拟地址 " , 是程序在执行时使用的地址 , 应用程序通过 逻辑地址 来访问数据或指令 , 而 不需要 直接操作物理内存 ;
逻辑地址 来源 : 逻辑地址 是 在 用户应用程序 运行过程中 由 CPU 生成的地址 , 开发者 或 编译器 并不直接关心物理内存的具体位置 , 只关注逻辑地址的空间 ;
逻辑地址 到 物理地址 的 映射 : 操作系统通过 虚拟内存管理机制 将 逻辑地址 映射到 物理地址 , CPU 发出的 逻辑地址 需要通过 页表、段表 等 映射机制 转换成物理地址 ;
2、物理地址
物理地址 定义 : 物理地址 是 计算机 内存 中实际的地址 , 指向系统物理内存中的具体位置 , 所有 实际的 存储操作 最终都会转化为物理地址 ;
物理地址 来源 : 物理地址 对应的是 计算机硬件 层面内存的真实位置 , 通常 由 操作系统 和 内存管理单元 ( MMU , Memory Management Unit ) 来管理 ;
物理地址 被 内存控制器 用来访问实际的内存单元 , 程序虽然使用逻辑地址 , 但内存访问最终都依赖物理地址 ;
3、逻辑地址 与 物理地址 区别
比较项 | 逻辑地址(虚拟地址) | 物理地址 |
---|---|---|
定义 | 由CPU生成的程序地址,独立于物理内存 | 计算机物理内存中的实际地址 |
别名 | 虚拟地址(Virtual Address) | 真实地址(Real Address) |
访问方式 | 程序访问的地址,由CPU生成 | 经过地址映射后访问的最终内存地址 |
地址空间 | 每个进程有自己的逻辑地址空间 | 由计算机硬件决定的物理内存空间 |
管理方式 | 由操作系统和MMU(内存管理单元)映射到物理地址 | 由内存控制器直接管理 |
转换方式 | 需要通过页表、段表或MMU转换 | 无需转换,直接用于访问内存 |
可变性 | 在程序运行时可变化,由操作系统动态管理 | 由硬件固定分配,通常不会改变 |
示例 | 进程访问地址 0x12345 | 物理内存地址 0xABCD345 |
4、逻辑地址 与 物理地址 的转换
在 应用程序 中 , 如果要 查询 内存中的数据 , 首先 要找到数据在 用户程序 中的 逻辑地址 , 然后 去 页表中查询 该 逻辑地址 对应的 物理内存 中的 物理地址 ;
逻辑地址 与 物理地址 之间的转换 由 内存管理单元 ( MMU , Memory Management Unit ) 完成 的 , 转换过程如下 :
- CPU 生成逻辑地址 : 用户应用程序 给出要访问的 逻辑地址 , 并将其传递到 CPU , 逻辑地址 由 页号 和 页内偏移 组成 , 页号 用于查找对应的物理页框 , 页内偏移在页框中保持不变 ;
逻辑地址 = [页号] + [页内偏移]
- 查找页表 : CPU 根据 当前进程 的 页表 将 逻辑地址 转换为 物理地址 , 操作系统维护一个 页表 , 用于记录逻辑页号与物理页框号的映射关系 , CPU 取出 逻辑地址 中的 页号 , 然后查找页表 , 找到对应的物理页框号 ;
- 生成物理地址 : 物理地址由 页框号 加上 页内偏移 组成 , 上个步骤得到了 页框号 , 直接与 页内偏移 组合成 物理地址 ;
物理地址 = [物理页框号] + [页内偏移]
- 访问物理内存 :
三、页表结构 和 物理内存淘汰机制
1、页表的结构简介
页表 ( Page Table ) 是 页式存储 管理中的关键数据结构 , 用于管理 逻辑地址 到 物理地址 的映射 ;
每个 进程 都有自己的页表 , 页表 存储在内存中 , 由 MMU ( Memory Management Unit , 内存管理单元 ) 负责 查询 和 转换 地址 ;
页表 结构 字段如下 :
- 页号 ( Page Number ) : 逻辑地址 中的 索引 , 用于 查找页表项 ;
- 页帧号 ( Page Frame Number, PFN ) : 物理内存中的 页框号 , 指向数据所在的物理页 ;
- 状态位 ( Valid/Invalid Bit ) : 指示该页是否有效(有效页 = 1,不在内存 = 0), 记录该 内存页 是否 从 磁盘 ( 外存 ) 中 加载到了 内存 中 ;
- 如果为 0 , 表示 内存页面 没有在内存中 ;
- 如果为 1 , 表示 内存页面 在内存中 ;
- 访问位 ( Accessed Bit ) : 记录该页 最近 是否被访问过 , 操作系统可用它进行页面置换 ;
- 如果为 1 , 表示 内存页面 最近有被访问过 ;
- 如果为 0 , 表示 内存页面 最近没有被访问过 ;
- 时间限制 : 如果 之前有被访问过 , 值为 1 , 但是经过一段时间内没有被访问 , 则会被 置为 0 ;
- 修改位 ( Dirty Bit ) : 记录该页是否被修改过 ( 1 = 已修改,需要写回磁盘 ) ;
- 如果为 1 , 表示 内存页面 最近有被修改过 ;
- 如果为 0 , 表示 内存页面 最近没有被修改过 ;
页表是逻辑地址到物理地址转换的核心 , 利用状态位、访问位、修改位进行内存管理和页面置换 ;
在现代计算机中 , 通常采用 多级页表 或 反向页表 优化存储和访问性能 ;
2、物理内存 的 淘汰机制
下图中 , 操作系统 只为该 进程 分配了 4 个 物理内存页 ;
对 上述表格 的 状态位 进行分析 :
系统为该 进程 的 1 / 1 / 2 / 5 页号 逻辑内存页 , 分配了 2 / 3 / 5 / 6 页帧号 对应的 物理内存页 ,
3 / 4 页号 的 逻辑内存页 对应的 物理内存页 对应的数据 没有被加载到 物理内存中 , 这部分数据 在 外存 ( 磁盘 ) 中 ;
要访问的 数据 没有加载到 物理内存 的情况 :
如果 想要访问 3 号页 逻辑内存 中的数据 , 但是其 对应的 数据不在 物理内存 中 ,
想要将 3 号页 对应的数据 从 磁盘 加载到 内存 中 , 需要淘汰掉当前的一个 物理内存 页 , 然后再加载对应的 磁盘数据 ;
淘汰 物理内存 页 是有一定的规则标准的 ;
已分配 的 物理内存页 的淘汰原则 :
要淘汰的 是 状态位 为 1 的 物理内存页 , 状态位 为 0 说明没有为 该逻辑内存 分配 ,
之后 根据 访问位 和 修改位 来决定要淘汰哪个 物理内存页 ;
优先淘汰 访问位 为 0 的物理页 ;
如果有多个 物理页 访问位 为 0 , 则继续看 修改位 , 优先淘汰 修改位 为 0 的物理页 ;
3、物理内存 的 淘汰机制 总结
物理页面 淘汰原则总结 :
- 状态位为 1 : 这是 前提条件 ;
- 访问位为 0 : 访问位 为 0 的 页面 优先淘汰 ;
- 修改位为 0 : 如果出现多个 访问位 为 0 的页面 , 考虑 优先淘汰 修改位 为 0 的页面 ;
- 因为 修改位 为 1 , 系统开销更大 , 将内存数据进行修改 , 会消耗更多的 资源和性能 , 消耗了这么多修改数据 , 将其直接淘汰 不划算 ;
4、案例分析
某个 用户进程 有 8 个 逻辑页面 , 页号为 0 ~ 7 , 每个 内存页大小为 4KB ;
操作系统 为 该 用户进程 分配了 4 个 物理内存 存储块 , 进程的 当前 页表 数据如下 :
逻辑地址 转 物理地址 案例计算
页大小为 4KB = 4096 Byte , 也就是 2 12 = 4096 2^{12} = 4096 212=4096 字节 , 4096 个存储单元的取值范围是 0b 0000 0000 0000 ~ 0b 1111 1111 1111 ;
页内地址 / 页内偏移 必须要 12 位 二进制数 才能 表示 ,
给定 4KB 的页大小 的 逻辑地址 , 低位 12 位是其 页内地址 或 页内偏移 , 高位就是 页号 ;
0x 5148 对应的二进制数为 0b 0101 0001 0100 1000 ,
- 低 12 位 为 0b 0001 0100 1000 , 这是 页内偏移 ;
- 高 4 位 为 0b 0101 , 这是 页号 , 对应十进制为 5 , 逻辑页号为 5 ;
查询 页表 , 逻辑页号 5 对应的 物理页帧号为 3 , 对应二进制为 0b 0011 页帧号 , 与 低 12 位 的 页内偏移 0b 0001 0100 1000 组合 ,
得到的 物理地址 为 0b 0011 0001 0100 1000 , 转为 16 进制为 0x 3148 ;
物理地址 页面淘汰 案例计算
计算 如果要访问 逻辑页面 6 , 需要淘汰的页面 :
从 状态位 为 1 的 内存页 中查找 要淘汰的页面 , 逻辑页号 1 / 2 / 5 / 7 对应的页面是已经分配 物理内存 的页面 ;
上述 四个页面中 , 逻辑页 2 的 访问位 为 0 , 说明最近没有访问 , 淘汰掉 逻辑页 2 ;