9.3 虚拟内存作为缓存的工具
虚拟内存和物理内存的分页
虚拟内存可以分为:
- 未分配的,没有数据和它们相互关联,不占用磁盘空间。
- 缓存的,当前已经缓存在物理内存中的已分配页。
- 未缓存的,未缓存在物理内存的已分配页。
页表:
页表将虚拟页映射到物理页。页表是由页表条目(PTE)组成的数组。
PTE由一个有效位和一个n位地址字段(物理页号或者磁盘地址)组成。
有效位表示该虚拟页是否被缓存在主存中。
主存的映射是全链接的,即任意物理页都可以包含任意虚拟页。
缺页:
缺页异常是,读取对应的页表条目,根据标志位发现不在主存内,那么进行换页。
目前现代系统都是使用按需页面调度。
局部性原理
抖动:工作集超过物理内存的话,容易发生抖动,即页面不停换入换出。
9.4 虚拟内存作为内存管理工具
操作系统为每个进程提供了一个独立的页表,完成了进程的隔离和保护。并且多个虚拟页面可以映射到同一个物理页面上。
虚拟内存简化了链接和加载、代码和数据共享,以及应用程序内存的分配。
- 简化链接:独立的地址空间运行每个进程的内存映像使用相同的基本格式,而不需要在意实际的存放位置。
- 简化加载:加载器不需要从磁盘把数据复制到内存,只需要每个页面被引用时,虚拟内存系统自动的调入数据页。
- 简化共享:可以将不同进程的虚拟页面映射到相同的物理页面,从而实现共享一份代码/数据。
- 简化内存分配:分配的虚拟内存页面是连续的,而物理地址的页面可以是不连续的。
Linux可以使用mmap的系统调用来允许程序自己做内存映射。
9.5 虚拟内存作为内存保护的工具
有些页表会有许可位,方便区分内核模式才能访问的页面和普通页面。如果不在内核态的程序访问了内核才能访问的页面,linux会把这种异常报告为:段错误(segmentation fault)
9.6 地址翻译
页表寄存器
n位的虚拟地址包含两部分:一个是p位的虚拟页面偏移和一个n-p位的虚拟页号。
页面命中时,CPU硬件执行的顺序:
- 处理器生成一个虚拟地址,并传给MMU
- MMU根据虚拟页号生成PTE地址,并从高速缓存/主存中请求。
- 高速缓存/主存 返回给 MMU需要的页表条目
- MMU构造物理地址,并传给高速缓存/主存
- 高速缓存/主存返回请求的数据给处理器
页面命中全部由硬件来处理,缺页需要操作系统内核参与
缺页时,执行顺序
1-3步同上
4. PTE有效位是零,发生了缺页中断,传递控制到操作系统内核的缺页异常处理程序
5. 确定牺牲页,如果页面被修改过,则换出到磁盘
6. 调入新的页面,修改PTE
7. 再次执行导致缺页的指令,成功返回虚拟地址给MMU,...
可以使用块表加速地址翻译。
多级页表减少页表大小。