虚拟内存与分配

Posted by JimWang on 2021-01-31

虚拟内存与分配

虚拟内存

虚拟内存的基本思想是,每个进程有用独立的逻辑地址空间,内存被分为大小相等的多个块,称为页(Page).每个页都是一段连续的地址。对于进程来看,逻辑上貌似有很多内存空间,其中一部分对应物理内存上的一块(称为页框,通常页和页框大小相等),还有一些没加载在内存中的对应在硬盘上

虚拟内存实际上可以比物理内存大。当访问虚拟内存时,会访问**MMU(内存管理单元)**去匹配对应的物理地址,而如果虚拟内存的页并不存在于物理内存中,会产生缺页中断,从磁盘中取得缺的页放入内存,如果内存已满,还会根据某种算法将磁盘中的页换出。

而虚拟内存和物理内存的匹配是通过页表实现,页表存在MMU中

没有虚拟内存的问题

  • 多个程序需要运行,但是内存空间不足了,就需要将其他程序暂时拷贝到硬盘当中,然后将新的程序装入内存运行.由于大量的数据装入装出,内存的使用效率低
  • 程序可以直接访问物理内存,一个进程可以修改其他进程的内存数据
  • 多线程情况下,不知道哪些物理内存可用

虚拟内存主要提供了如下三个重要的能力:

  • 它把主存看作为一个存储在硬盘上的虚拟地址空间的高速缓存,并且只在主存中缓存活动区域(按需缓存)。
  • 它为每个进程提供了一个一致的地址空间,从而降低了程序员对内存管理的复杂性。
  • 它还保护了每个进程的地址空间不会被其他进程破坏。

内存分配

内存分配申请的是虚拟的内存空间,并没有拿到真正的物理内存空间。但是在第一次访问该内存的时候,程序会发现虚拟内存地址没有影射到物理内存地址,于是触发缺页中断(异常)

此时,进程会陷入内核态,执行一下操作:

  1. 检查要访问的虚拟地址是否合法
  2. 查找分配一个物理页
  3. 填充物理内容(读取磁盘,或者直接置0)。
  4. 建立虚拟内存和物理内存的映射关系

逻辑地址和物理地址的映射

分页机制

程序或操作系统逻辑地址分为多个(page),将物理地址分为多个(page frame 也叫页,这里方便区分称为帧)。

逻辑地址页到物理地址帧的映射称为 页表(page table)。页号和帧号进行映射,其实页表不仅仅存了映射关系,还存当前页、帧的状态(例如是否可用,权限是否足够等)。

image-20210131231106127

每一个进程都有一张自己的页表

分页内存寻址过程小例子

机器:32位操作系统 256MB内存 页大小4KB

程序:32位

4K=12bit

逻辑地址 32bit=20bit页号+12bit偏移

物理地址 28bit=16bit帧号+12bit偏移

对于地址0x000011a3 页号00001 偏移 1a3。根据页号找到帧号,帧号+偏移=物理地址。

image-20210131231835787

根据页号去页表中找到对应帧号,对应帧号+偏移量就是真实物理地址

  1. 如果查表后发现帧号是磁盘会发生什么?

这时候会触发缺页中断,切换到内核态,内核从磁盘读取数据加载到内存中,然后把物理地址在page table进行更新,然后重新进行内存寻址的过程。

  1. 如果从磁盘加载进内存时,内存帧满了怎么办?

这时候会触发页面置换(页面置换算法),将不太常用的帧 从RAM中逐出到磁盘中,让出位置来存储。