0%

再探虚拟内存

本文是笔者读《深入理解操作系统》的虚拟内存部分的读书笔记。本文总结了书中提到的虚拟内存的这几个方面:

  1. 虚拟内存的作用;
  2. 引入虚拟内存后,地址翻译的过程
  3. TLB和cache的结合使用
  4. 多级页表的引入
  5. Linux中虚拟内存的组织方式
  6. 内存映射和共享对象/私有对象

首先是虚拟内存的作用,在书中,主要解释了虚拟内存有三个作用:

  1. 作为缓存的工具;
  2. 作为内存管理的工具;
  3. 作为内存保护的工具;

(一)最主要的功能,作为缓存的工具

虚拟内存的概念

虚拟内存在概念上是磁盘上的连续数组,分为三个部分:

  1. 没有分配的:VM还没有分配或者创建的页,不占用磁盘空间
  2. 已缓存的:已经缓存在物理内存的页;
  3. 未缓存的

注意这里首先是磁盘上一个连续的数组,其次是这个数组中有空的“缝隙”,也就是没有分配的页。当我们调用malloc函数的时候,就是从这些没有分配的页中取出足够大的来进行分配;

虚拟内存的一些细碎说明

  • 虚拟内存被分为一页一页的,大小和物理内存的页一样;
  • 主存的任何物理页都可以存任何虚拟页;
  • 操作系统为每一个进程都准备了独立的页表,每个进程有独立的虚拟地址空间
  • 页表的大小为页的大小;
  • 页的大小为4KB(LInux中)

为了完成虚拟内存系统,需要软硬件协作:

一些部分的作用:

  1. 页表,存储虚拟页对应的物理页地址,是否缓存等信息;
  2. MMU把虚拟地址通过查页表转换成物理地址
  3. 操作系统,维护页表的内容,并进行页的传输

(二)简化内存管理

  1. 简化链接;允许每个进程的虚拟地址空间都使用相同的基本格式;
  2. 简化加载;新创建的进程要加载数据段和代码段,Linux首先分配相应的虚拟页(磁盘空间),然后再把页表相应的标记为设置为无效,虚拟内存系统自动去加载;
  3. 简化共享;不同页表映射到同一个物理页;
  4. 简化内存分配:在虚拟地址空间中,malloc分配的多个页的空间必须连续,但是通过页表,其在物理内存中的分布可以不连续;

(三)作为内存保护的工具

内存管理应该保证安全的进程隔离,用户态和内核态的隔离,这些隔离可以通过在PTE上简单的添加一些标识位完成;

地址翻译的过程

结合了高速缓存的地址翻译过程

结合TLB加速地址翻译

TLB:在MMU中,可以直接把虚拟地址翻译成物理地址,MMU翻译的时候直接去TLB中看看有没命中,命中了直接把PTE拿来翻译成物理地址(PA),然后再访问主存;

TLB中每一行都是一个PTE;

[]https://cdn.jsdelivr.net/gh/libertyunionkjy/jykeImg/images/202112111615514.png)

多级页表

为什么需要多级页表?压缩页表占用的空间

  • 一级页表必须在主存中;
  • 二级页表在需要的时候创建、调入、调出;

LInux的虚拟内存

LInux怎么组织虚拟内存?

LInux把虚拟内存组织成区域,也就是我们熟悉的段。

看上图,需要说明的是mm_struct中的字段pgd和mmap字段,pgd指向第一级页表的基地址,后面放到CS3控制寄存器中;mmap指向一个vm_area_structs的链表;

我们常说进程的虚拟内存空间分为代码段、数据段、bss段、堆栈段,这些区域就是通过vm_area_struct进行唯一的识别的。创建了一个vm_area_struct则是创建了一个新的虚拟内存区域,Linux进程可以通过mmap函数来创建一个虚拟内存区域。munmap函数来删除一个虚拟内存区域。

Linux怎么进行缺页异常处理

MMU在翻译虚拟地址A的时候触发缺页异常,会转移到内核的缺页处理程序,内核会进行以下的检查:

  1. 看虚拟地址A是不是合法?是不是在某一个区域?如果不在某一个区域,就会触发段异常,标志为1,进程会被终止;
  2. 找到对应的区域后,内核会检查对这个内存区域的操作是否合法,如果不合法,会触发保护异常,标识为2;
  3. 最后,内核会判定这个访问是合法的,会进行换页操作,然后再吧虚拟地址发送到MMU,就不会触发缺页异常了;

内存映射

什么是内存映射?Linux将一个虚拟内存区域磁盘对象关联起来以初始化这个内存区域的过程。

磁盘对象可以有两种:

  1. 普通文件:
  2. 匿名文件

一旦一个页面初始化过后,就在交换空间(swap space)之间换来换去。

共享对象和私有对象

  1. 共享对象:进程对共享对象的写操作也对其他进程可见
  2. 私有对象:采用写实复制的方法

一些名词

  • PTE:页表条目
  • SRAM:高速缓存,也就是CPU里面的L1,L2,L3缓存
  • DRAM:物理主存
  • TLB:Translation Lookaside Buffer,翻译后备缓冲器,这玩意儿在MMU中
  • VPO:虚拟页面偏移量
  • VPN:虚拟页号
  • PPO:物理页面偏移量
  • PPN:物理页号