操作系统---内存管理(中) 分页存储
内存管理学习笔记 :
操作系统---内存管理(上) 概念 覆盖交换技术 连续分配管理方式
操作系统---内存管理(下) 分段存储 段页式存储 虚拟内存 请求分页管理方式
上一节 : 操作系统---内存管理(上)
大纲 :
基本分页存储管理
页框和页面
思想 : 把内存分为一个个相等的小分区, 再按照分区大小把进程拆分成一个个小部分.
-
页框 :
-
页面 :
注意区分页框和页面的概念, 页框是针对内存的, 页面是针对进程的
地址转换的实现
- 特点 : 页面离散存放, 但是页面内部连续存放
- 访问逻辑地址A : ( 重点 )
- 确定逻辑地址A的 " 页号 " P
- 找到P号页面在内存中的起始地址 ( 需要查找页表 )
- 确定逻辑地址A的 " 页内偏移 " W
- 逻辑地址 A的物理地址 = P号页面在内存中的起始地址 + 页内偏移量W
页号和页内偏移量
e.g.
为了方便计算页号和页内偏移量, 页面大小一般设置为2的整数幂( why ? ) :
( 妙啊 )
页表
tips : 页表中的页号是"隐含"的, 可以不占用存储空间
e.g.
假设某系统物理内存大小为 4GB, 页面大小为 4KB, 则
每个页表项至少应该为多少字节?
- 内存块大小=页面大小=4KB= $ 2^{12} $B
- 4GB 的内存总共会被分为$ \frac{ 2^{32} }{ 2^{12} } = 2^{20} $个内存块
- 内存块号的范围应该是 0 ~ $ 2^{20} -1 $
- 内存块号至少要用 20 bit 来表示
- 至少要用3B来表示块号(3*8=24bit)
(但是, 为了方便页表的查询, 常常会让一个页表项占更多的字节, 使得每个页面恰好可以装得下整数个页表项)
- 如何理解 "页号是隐含的" :
基本地址变换机构
框图 : ( 重点 ! )
步骤总结 :
-
根据逻辑地址计算出页号和页内偏移量
-
判断页号是否越界
-
查询页表, 找到页号对应的页表项, 确定页面存放的内存块号
-
用内存块号和页内偏移量得到物理地址 ( 页表长度*物理块号 + 页内偏移 = 物理地址 ( 计算机直接采用拼接物理块号和页内偏移的方式得到物理地址 ) )
-
访问目标单元
( 一共需要访问两次内存 : 第一次用来查页表, 第二次用于访问目标内存单元 )
具有快表的地址变换机构
局部性原理
-
时间局部性
如果执行了程序中的某条指令, 那么不久之后这条指令很有可能再次执行; 如果某个数据被访问过, 不久之后该数据很可能再次被访问
( 程序中存在大量的循环 )
-
空间局部性
一旦程序访问了某个存储单元, 在不久之后, 其附近的存储单元也很有可能被访问到
( 很多数据在内存中连续存放 )
快表(TLB)
快表又成为联想寄存器(TLB), 是一种访问速度比内存块很多的高速缓冲存储器, 用来存放当前访问的若干页表项, 以加速地址变换的过程. 与此对应的, 内存中的页表常称为慢表.
步骤总结 :
快表与基本地址变换机构的比较 :
tips : TLB 和 普通 Cache 的区别——TLB 中只有页表项的副本, 而普通 Cache 中可能会有其他各种数据的副本
两级页表
单级页表存在的问题 :
- 由于页号隐式表示, 所以要根据页号查询页表需要 :
K 号页对应的页表项存放位置 = 页表始址 + K * 4
要在所有的页表项都连续存放的基础上才能用这种方法找到页表项
- 同时, 由局部性原理可知, 很多时候, 进程在一段时间内只需要访问某几个页面就可以正常运行了, 因此没有必要让整个页表都常驻内存
解决 : 把页表再分页并离散存储, 然后再建立一张页表记录页表各个部分的存放位置, 称为页目录表, 或称外层页表, 或称顶层页表.
e.g.
关于页表常驻内存的解决 -- ( 虚拟存储技术 ) , 在页表项中增加一个标志位, 用于表示该页面是否已经调入内存
注意:
-
如果采用多级页表机制, 各级页表不能超过一个页面
-
两级页表的访存次数分析 :
n级页表访存次数为n+1次: ( 以2级页表为例 )
- 访问内存中的页目录表 ( 顶级页表 )
- 访问内存中的二级页表
- 访问目标内存单元