虚拟内存

虚拟内存的出现是为了解决程序大于内存问题,其基本的思想是:每个程序拥有自己独立的地址空间,这个空间被分成多个块,每个块称作一页面。每一页有连续的地址范围。这些页被映射到物理内存,但并不是所有的页都必须在内存中才能运行程序。

由程序产生的地址称为虚拟地址,所有的虚拟地址共同构成了虚拟地址空间。在没有内存管理单元(MMU)的计算机上,这些虚拟地址将直接送到内存总线,读写具有相同地址的物理内存。在使用MMU的计算机上,这些虚拟地址先送到MMU,由MMU映射为物理内存地址,再送到内存总线。

页表

基本概念

虚拟地址空间按固定大小划分成若干单元,每一单元被称为页面,在物理内存中对应的单元称为页框。一个程序的页面数量往往大于页框数量,需要建立页面与页框的映射关系,完成虚拟地址向物理地址的转换。

页表负责把虚拟页面映射为页框,虚拟页号为页表的索引,由此找到虚拟页面对应的页表项,由页表项可以找到页框号。

具体映射过程

假设虚拟地址空间有16个页面,每个页面大小4KB。以16位虚拟地址为例,则其高4位可以表示16个页面,低12位可以表示一个页面的全部4096个字节。以虚拟地址8196为例,其二进制表示形式0010000000000100,则其虚拟页号为0010,在页表中索引0010对应的页表项,假设为110,即对应页框号为6,则页框号与低12位偏移共同构成了15位的物理地址,送入内存总线。

上述转换规则可以简化成以下过程:

  1. 由虚拟地址提取出虚拟页面号(高位部分)和页内偏移量(低位部分)
  2. 使用虚拟页面号在页表内进行索引,查询该页表项对应的页框号
  3. 将页框号和页内偏移量重组成物理地址,送入内存总线

缺页

当页表内存在虚拟页面号对应的页框时,不会产生缺页中断缺页错误。页表项中会有一个“在/不在“位来表示虚拟页面有没有被映射,当页表内没有对某一虚拟页面的映射时,访问该虚拟页面会引起缺页中断或缺页错误。此时操作系统会建立内存中的一个页框和该虚拟页面的映射关系,保存在页表中。当然,该页框可能来源于未被使用或将很少使用的页框落盘后回收。

MMU

基本概念

内存管理单元的三个主要作用:

  • 提供虚拟地址和物理地址的映射
  • 内存访问权限保护
  • Cache缓存控制

MMU的存在可以为系统的每个用户进程分配独立的内存空间,并且保证了用户空间不能访问内核空间地址,为操作系统实现内存管理模块提供硬件基础。

时间空间问题

采取了虚拟内存和页表的分页系统往往会面临以下两个问题:

  • 时间上:虚拟地址到物理地址的映射必须要快
  • 空间上:如果虚拟空间地址很大,页表也会很大

针对时间问题,MMU设计了转换检测缓冲区(Translation Lookaside Buffer, TLB),也称为快表,是MMU的核心部件。根据长期的观察,大多数程序总是对少量的页面进行多次的访问,因此缓存少量的虚拟地址与物理地址的映射关系,可以加快映射速度。如果在TLB中没有要访问的虚拟页面的映射关系时,就需要去内存中访问页表,查询虚拟页面和页框的映射关系。

针对空间问题,有两种方法:多级页表倒排页表。多级页表的引入避免把全部页表一直保存在内存中。倒排页表则基于这种思想:让页框对应页表中的页表项,而非每一个虚拟页面去对应页表项(由于页面数量大于页框数量,这样相当于增加了映射复杂度,但减小了页表的大小)。

访问流程

不详述,请看下图,结合知识自行回忆思考,以加深理解。

参考文献

  1. 《现代操作系统》3.3 虚拟内存
  2. 《Linux设备驱动开发详解》 第11章 内存与I/O访问
说点什么
请文明发言!
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...