虚拟内存和物理内存

虚拟内存可以是物理内存的1.5-3倍左右,为什么可以突破物理内存的限制呢?
这个问题其实想了解很久了。

那必定是有个表格,来映射程序的虚拟内存到实际物理内存。

简单页表:类似数组,时间复杂度为 O(1)。但空间复杂度为数组的长度,即页的个数。32 位的内存地址为 4MB(= 2^20 * 4byte)= 4MB 左右,把32位的内存,前20位用来当成页号,后12位当作偏移量。想知道物理内存,只需要在这个页表查到相应的物理页号,再加上自己本身的偏移量,就可以知道实际物理地址。
(PS: 1K byte=1KB,1 Million Byte等于4MB, 2^20 = 1048576)

但是一个程序就需要维护一个4mb页表,一部机器运行1000个程序都是常态,这样内存需要维护的页表为4GB。完全不可行

多级页表(页表树):类似b+树,把20为的页表号分成4段,每段总共5个位。每个段对应一个页表,举个例子:
00011, 10011, 00110, 11011, 偏移量
根据第一段 00011 到4级页表,找到其3级页表(多个)
根据第二段 10011 到其3级页表,找到对应的2级页表(多个)
根据第三段 00110 到其2级页表,找到对应的1级页表(多个)
根据第四段 11011 到其1级页表,找到对应的物理页表号,再加上偏移量。

一级的页表可以映射到 2^5 = 32 条记录,数组长度为32,同时每个元素4byte,那么就是128byte的长度。 323232*128byte一样的大小,但是由于只有一级页表会存储在内存里。

举个例子:
校长的公文包里,每次只需要带上一张表,这张表记录了一千个班,每个班的班主任手机号。
当校长想找某个学生时,

  1. 先根据学号,计算出他在哪个班。
    2.在表中找到这个班,里面有这个班的班主任手机号。
    3.打电话给班主任,班主任再送来他们班的一张表,表中记录了这个班每个学生的手机号。
    4.校长再根据学号,再这个班的班级表中找到这个学生和他的手机号。
    从此,校长的公文包只需要带上一张总表就行,需要找哪个学生时,就把对应班的班级表放到包里,比如校长今天只想找 3班和4班,那么公文包里最多放三张纸即可。
    (PS 这里我认为原文没讲清楚)

这个时候需要访问4次内存才能确定物理地址,也就是访问的次数增加了。
但是由于,寻找虚拟地址和物理地址的访问,其实是有局部定律的,那么对于一个页而言,可以使用缓存机制。

地址变换高速缓冲(Translation-Lookaside Buffer,TLB)
CPU 内封装了 MMU, 内存管理单元,和TLB,其中TLB分指令TLB(即ITLB)和数据TLB(DTLB),这些缓存已经存放了之前做地址转换的的时候结果,所以不需要麻烦的多此访问多级页表。