本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、使用虚拟存储器的原因
- 程序的可寻址地址空间大于主存的实际容量
- 实际使用的内存空间大于主存的实际容量
- 多个进程的地址空间重叠,每个进程理论上可以使用全部内存
二、虚拟存储器的层次化存储结构
虚拟存储器的核心思想:将一部分数据存储在硬盘上,提高内存的存储能力
存储在硬盘上的部分称为页面文件(page file)
项目\存储器类型 | 高速缓存 | 虚存 |
---|---|---|
上层存储器 | - | 主存 |
下层存储器 | 主存 | 硬盘 |
存储单元 | 块 | 页 |
上层地址 | 块号+偏移 | 物理地址 |
下层地址 | 内存地址 | 虚拟地址 |
映射机制 | 内存地址转为缓存地址 | 细泥底质转为物理地址 |
失效 | 缓存失效 | 页面故障 |
上层已满的处理 | 缓存块替换 | 页替换 |
三、页
将每个进程的虚拟内存和系统物理内存划分为固定大小的数据单元,称为页(Page)
在物理内存中仅保存一部分进程的一部分页,虚拟内存页(虚页)需要经过地址转换为物理内存中的页
物理内存中的页称为页面(Frame/Page Frame)
页表
页表保存了每个进程的虚拟内存页与物理内存页的地址转换关系,一般保存在内存里
每个进程有独立的页表
四、虚存地址转换
和缓存类似,虚拟内存同样通过对地址的分解实现地址转换
虚拟地址分为两个字段
- 页编号(Page No.):该页在虚拟内存中的编号
- 页内偏移值(Offset):该地址在虚拟内存中对应页内的偏移值
物理地址分为两个字段
- 页面编号(Frame No.):该页在物理内存中对应的页面编号
- 页内偏移值(Offset):该地址在对应页面中的偏移值
例:假设一个按字节寻址的系统支持13位虚拟地址,物理内存采用12位地址,页面大小为1024B,求以上字段长度
虚拟地址共13位
偏移值长度=log2(1024)=10
页编号长度=13-10=3
物理地址共12位
偏移值长度=log2(1024)=10
页编号长度=12-10=2
例:假设一个按字节寻址的13位系统,物理内存大小为4KB,页面大小为1KB,且进程1的页表如下,请问下列虚拟地址对应的物理内存地址分别是多少?
- 0x1553
- 0x0802
- 0x1004
由上图知道:
虚拟地址中:Page范围0~7,因此虚页号长度为log2(8)=3,偏移量10
物理地址中:Frame范围0~3,页号长度为2,偏移量10
1.
0x1553=101 0101010011,查第五页,页面编号1,有效位1
物理地址=01 0101010011=0x0553
2.
0x0802=010 0000000010,查第二页,页面编号0,有效位1
物理地址=00 0000000010=0x0002
3.
0x1004=100 0000000100,查第四页,页不在内存中,发生页面故障
分页内存管理的有效访问时间
访问一次虚拟内存需要两次内存访问:第一次访问页表,第二次访问物理地址
例:假设访问主存时间为200ns,发生页面失效的处理时间是10ms,求页面是效率是1%和0%的有效访问时间
1.失效率1%
t = 99% × (200ns+200ns) + 1% × 10ms = 100396ns
2.失效率0%
t = 200ns+200ns = 400ns
注意两次内存访问
五、转译后备缓冲器(TLB)
以下是设计初衷:
- 为了减少访问内存的时间:使用高速缓存
- 为了减少访问页表的开销:使用转换后备缓冲器(Translation Lookaside Buffer, TLB)
TLB用以提高访问页表的效率
TLB的原理通过层次化存储结构提高访问页表的速度,TLB是特殊的缓存,其保存虚拟页编号到物理页面编号的映射,通常采用相联缓存实现
使用TLB的页面访问过程
- 从虚拟地址中提取出页号和偏移值
- 在TLB中查找虚拟页号对应的表项
- 如果找到,则用对应的物理页号和偏移值生成物理地址
- 如果未找到,需要访问内存中的页表
- 如果该页在主存中,根据页表中的页面编号和偏移值生成物理地址,并更新TLB
- 否则发生页面故障,触发中断,通常中断程序需要将页面加载到内存中,更新页表和TLB