为什么使用虚拟内存?

  • 如果程序直接使用虚拟内存的话,那么想在内存中同时运行两个程序是不可能的。如果第一个程序在2000物理地址写入一个新值,将会擦掉第二个程序存放在相同位置上的所有内容,所以同时运行两个程序是行不通的;
  • 进程操作的是虚拟地址,通过操作系统的机制,将不同进程的虚拟地址和不同内存的物理地址映射起来;换句话说,就是由操作系统为我们提供写入内存的操作,避免了多个进程对同一个内存的使用;

操作系统如何管理虚拟内存与物理内存的关系?

内存管理单元(MMU:将虚拟内存地址转换为物理地址的工作;

内存分段

  • 虚拟内存通过段表与物理地址进行映射的;
  • 虚拟内存地址通过段号,作为段表的索引,找到段表里的这一项的段基地址;将段基地址 + 段内偏移量就得到物理地址;

造成问题

  • 内存碎片:程序退出之后,会产生有很多空余内存,导致新的程序无法被加载;
  • 通过内存交换(内存与硬件进行交换,通过以硬件作为临时存储,将空余内存重新补上)解决了内存碎片的问题;但是如果交换的是一个占内存空间很大的程序就会导致内存交换效率低;

内存分页

  • 虚拟地址通过页表与物理地址进行映射;
  • 分页是把整个虚拟和物理内存空间切成一段段固定尺寸大小;
  • 虚拟内存地址通过页号,作为页表的索引,找到页表里这一项的页基地址;将页基地址 + 页内偏移量就得到物理地址;

如何解决分段的内存碎片、内存交换效率低的问题?

  • 由于内存空间都是预先规划好的,也就不会像分段会产生间隙非常小的内存;采用了分页,释放内存都是以页为单位进行释放的,也就不会产生无法给进程使用的小内存;
  • 如果内存空间不够,操作系统会把其他正在运行的进程中【最近没被使用】的内存页面给释放掉,也就是暂时写在硬盘上,称为换出;一旦需要的时候,再加载进来,称为换入;所以内存交换效率较高

可能会导致缺页异常

  • 因为通过内存分页的方式,当内存空间不够时,会将其他正在运行的进程中【最近没被使用的】内存换出;
  • 所以当CPU通过虚拟地址的页号访问页表的时候,可能不在物理内存中;这个时候就需要缺页异常,发送缺页中断请求;
  • 操作系统会先查询该页面在磁盘中的页面位置,将该页面换入到物理内存中;
  • 但是换入之前需要在物理页面寻找空闲页,如果找到则把页面换入到物理内存中;如果没有找到,说明物理内存已满,需要调用内存调度算法换出;
  • 之后CPU重新执行导致缺页异常的指令。

段页式内存管理

内存分段和内存分页组合使用,通常称为段页式内存管理。

思路:

  • 先将程序划分为多个有逻辑意义的段,通过内存分段机制;
  • 再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页。

实现方式:

  1. 通过段号,找到段表得到页表起始地址;
  2. 通过页表起始地址,找到页表,得到物理页号;
  3. 将物理页号 + 页内偏移量就得到物理地址。