在电脑中,进程能够看到的内存是系统想让进程看到的。在主流的内存管理中,有两种内存视图:直接使用物理内存,使用虚拟内存。
两种内存管理模式
这种直接访问物理内存的模式主要用于比较小的系统,如嵌入式微控制器汽车、电梯和数码相框等设备。因为在这些设备中运行的环境比较简单,而且在这种设备上面运行一个成熟的操作系统来控制页表等复杂数据结构也不太合适,有太多没有必要的消耗。
第二种就是比较大的计算机中常用的虚拟内存:
这种虚拟内存的管理模式用于几乎所有的现代服务器,笔记本与手机中;关于虚拟内存的思想可以说是计算机中最巧妙的思想之一。它能够在很多方面帮助操作系统更好的管理进程,后面慢慢会说到。
为什么会出现虚拟内存?
- 为了更有效率地利用主存:使用DRAM作为虚拟地址空间部分的缓存。
- 简化内存管理:每个进程获得相同的线性地址空间,这样能够简化链接的操作,进程不需要知道自己将会被加载到内存的哪个部分,链接的时候也不需要提前预知该程序会被加载到哪里,只需要按照标准的虚拟地址空间来链接就可以。
- 隔离地址空间:一个进程不能干扰另一个进程的内存,进程之间是看不到对方的虚拟地址空间的;每个进程都有一种只有自己占据了所有内存的错觉。同时虚拟内存也能够帮助控制访问权限,使用户程序无法访问特权内核的信息和代码。
作为缓存工具的VM
从概念上讲,虚拟内存是存储在磁盘上的N个字节的数组,磁盘上数组的内容缓存在物理内存(DRAM缓存)中。这些缓存块称为页(大小为 P = 2 p P = 2^p P=2p字节)。
DRAM的缓存管理是很复杂的,比Cache的管理要复杂特别多。究其原因是因为DRAM不命中造成的惩罚比Cache不命中造成的惩罚大很多(DRAM比SRAM慢十倍,但是Disk比DRAM慢整整一万倍)。所以人们绞尽脑汁发现了更复杂的更有效的算法来实现DRAM的缓存管理。
因为非常严重的不命中惩罚,造成的结果是:
- 很大的缓存块(page),一般是4KB,有时候是4MB。
- 全相联的缓存:
- 任何一个虚拟页可以放进任何一个物理页。
- 需要一个很“大”的映射函数,与Cache使用的不一样。
- 有一个很精妙但是很复杂,代价昂贵的交换算法。
- 太复杂并且开放,无法在硬件中实现。
- 更多的使用“写回”而不是“直写”,对于DRAM与Disk来说,直写的代价太大太大了。
页表就是元素为PTE(Page Table Entries)的数组,每个有效的PTE指向一个物理页。每个进程都有属于自己的页表,进程在进行上下文切换的时候也会切换页表。
页命中(Page Hit)就是PTE指向的物理页在物理内存上,如下图指向VP2: