Complete Virtual Memory Systems
通过VAX/VMS和LINUX两个系统来说明前面所说的部分在完整的VM系统中如何体现。
1. VAX/VMS Virtual Memory
1.1 Memory Management Hardware
VAX-11为每个进程提供了32位虚拟地址,page大小为512字节,即一个虚拟地址包含23位VPN和9位offset,VPN的高2位用于区分page所位于的segment。
为了解决由于page太小而使page table太大的情况,该系统使用了两种方法。
- 把user address space划分成两个segment。
- 把user page tables放置在内核虚拟内存中。
1.2 A Real Address Space
1.3 Page Replacement
VAX的PTE包含的位:1位有效位(valid bit)、4位保护位(protection bit)、1位脏位(dirty bit)、5位预留位(reserved bit)和剩余的PEN。没有参考位(reference bit),表明VMS替换算法必须在没有硬件支持的情况下确定哪些page处于活动状态。
还有一个问题就是当一个程序运行时使用了大量内存,那么其他程序就没有足够的内存可用。
为了解决上述两个问题。开发者提出了segmented FIFO替换策略:每个进程具有可以在内存中保留的最大page数,称为resident set size(RSS),每一个page都保存在FIFO列表中。当进程超出其RSS时,就把“先进”的page踢出。
当然,前面我们已经知晓FIFO算法的性能算不上最好。为了提高FIFO算法的性能,VMS引入了两个second-chance lists(clean-page free list & dirty-page list)放置那些被踢出来的page。
VMS的另一个优化就是clustering。就是集中大量需要交换的page然后一起进行交换。
1.4 Other Neat Tricks
VMS还有另外两个现在已成为标准的技巧:demand zeroing & copy-on-write。
2. The Linux Virtual Memory System
主要讨论Linux for Inter x86。
2.1 The Linux Address Space
主要感兴趣的就是上图中的Kernel(Logical)和Kernel(Virtual)。
2.2 Page Table Structure
上图所示,P1用于索引最顶层的page directory,然后进行翻译,P2~P4等级依次降低,直到page table的实际page被P4索引到为止。
随着技术的发展,现今已经有P5、P6和更多的等级划分了.......
2.3 Large Page Support
使用larger page不仅能够减少TLB Miss,而且正因为有了更短的TLB-miss路径,OS处理TLB Miss更迅速,内存分配也更快。
2.4 The Page Cache
Linux的page cache是统一的,主要有3个来源:
- memory-mapped files:来自设备的文件数据和元数据
- anonymous memory:每个进程的heap和stack pages
- page cache hash table:保存的实体
Linux为了解决程序采用LRU策略重复访问一个大文件,将所有其他文件踢出内存。更糟糕的是,该文件保留在内存中的部分内容从未被引用过这个问题,引入了2Q替换算法:第一次访问时,page放入一个queue中,重新引用该page时,该page将被提升到另一个queue中。
2.5 Security And Buffer Overflows
一个主要的威胁就是buffer overflow。下面问题代码:
为了防止该问题发生,AMD引入了NX (No-eXecute)bit,它只是阻止从任何在其相应PTE中设置该位的page执行。
但是黑客就是黑客,更聪明的使用ROP(return-oriented programming)。Linux为了防止该方法,引入了另一种防御机制ASLR(address space layout randomization):OS把code、heap、stack放置在任意的地址。看一下下面代码:
对于没有引入ASLR防御机制的机器,每次返回的stack的地址都是一样的。但是对于引入了ASLR的机器,返回的stack的地址都是随机的,如下所示: