深入理解虚拟内存


一个系统中的进程是与其他进程共享CPU和主存资源的,如果太多进程需要太多的内存,那么他们中的一些根本就无法运行。当一个程序没有空间可用时,就会无法运行;当某个进程不小心写了其他进程使用的内存时,他就可能以令人迷惑的方式挂掉。
为了更有效地管理内存并且少出错,现代系统提供了一种对主存的抽象概念,叫做虚拟内存VM。它为每一个进程提供了一个大的、一致的和私有的地址空间。
虚拟内存有三个重要的能力:1)它将主存看成是一个磁盘空间的高速缓存,在主存中只保存活动区域,并且根据需要在磁盘和主存间来回传送数据,这样可以更节约的使用主存;2)它为每个进程提供了一致的地址空间,从而简化了内存管理;3)它保护了每个进程的地址空间不被其他进程破坏。

1 物理和虚拟寻址

计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组,每个字节都有一个唯一的物理地址。第一个字节的地址是0,第二个是1,通过这种方式访问内存,我们称这种方式为物理寻址
在这里插入图片描述
早期的PC使用物理寻址,而且诸如数字信号处理器、嵌入式微控制器以及Cray超级计算机这样的系统仍然继续使用这种寻址方式。然后,现代处理器使用的是一种称为虚拟寻址的寻址形式。
在这里插入图片描述
使用虚拟寻址,CPU生成一个虚拟地址来访问主存,这个虚拟地址通过内存管理单元MMU进行的地址翻译获取到物理地址,利用存放在主存中的查询表来动态翻译虚拟地址,该表的内容由操作系统管理。

2 地址空间的概念

地址空间是一个非负整数地址的有序集合。如果地址空间的整数是连续的,那么我们说他是一个线性地址空间
一个地址空间的大小是由表示最大地址所需要的位数来描述的。在一个带虚拟内存的系统中,一个包含2^n个地址的虚拟地址空间就叫做一个n位的地址空间。现代系统通常支持2位或64位虚拟地址空间。
物理地址空间,当然就对应系统中物理内存的字节。
主存中的每个字节都有一个选自虚拟地址空间的虚拟地址和一个选自物理地址空间的物理地址。

3 虚拟内存作为缓存的工具

之前提到过,虚拟内存被当做是磁盘的高速缓存,那么是如何进行存储的呢。
磁盘设备为块设备驱动,磁盘上的数据被分割成块,这些块作为磁盘和主存之间的传输单元。VM系统通过将虚拟内存分割为称为虚拟页VP,这种大小固定的块来处理这个问题,每个虚拟页的大小为2^p字节。类似的,物理内存被分割为物理页PP(页帧),大小和虚拟页相同。

#获取块大小
sudo /sbin/tune2fs -l /dev/sda1|grep "Block size"
#获取页大小
getconf PAGESIZE

在任何时刻,虚拟页的都分为三部分:
1)未分配的,VM系统还未分配的页,没有任何数据与他们相关联,所以既不存储在磁盘也不存储在主存;
2)缓存的,已经缓存在物理内存中的页;
3)未缓存的,未缓存在物理内存中的页,存储在磁盘上。
在这里插入图片描述
如上图,0、3未存储在任何介质,1、4、6缓存在主存上,2、5、7存储在磁盘上。

3.1 页表

为了清理的理解不同层级的缓存概念,我们用SRAM缓存来表示位于CPU和主存之间的L1、L2和L3高速缓存,DRAM缓存来表示虚拟内存系统的缓存,它在主存中缓存虚拟页。
DRAM比SRAM要慢大约10倍,而磁盘要比DRAM慢大约100 000多倍。因此DRAM缓存的不命中比SRAM缓存的不命中要昂贵得多,这是因为DRAM缓存的不命中要由磁盘来服务,而SRAM缓存不命中通常是由基于DRAM的主存来服务的。而且从磁盘的一个山区读取第一个字节的时间开销比起读这个扇区中的连续的字节要慢大约100 000倍。
由于不命中代价和访问第一个字节的开销,虚拟页旺旺很大,通常是4KB~2MB。

虚拟内存系统可以通过某种方法来判断一个虚拟页是否缓存在DRAM中,如果命中,则可以通过MMU获取到物理页,如果未命中,虚拟内存系统将选择一个牺牲页,磁盘中的虚拟页替换掉这个牺牲页。
这些功能是通过MMU和存放在物理内存中的叫做页表的数据结构联合提供的。
在这里插入图片描述
如上图,页表就是一个页表条目PTE的数组。虚拟地址空间的每个页在页表中一个固定偏移量除都有一个PTE。我们这里假设每个PTE是由一个有效位和一个n位地址字段组成的。有效位表示该虚拟页是否缓存在DRAM中,地址字段表示在物理内存或磁盘中的地址,地址字段若为null则表示这个虚拟页未被分配。

3.2 页命中

如果CPU要读一块虚拟内存,而此时这个页缓存在了DRAM中,这种情况就是页命中。
在这里插入图片描述
如上图CPU要读VP2中的一段数据,判断有效位为1,说明VP2缓存在了DRAM中,那么根据第二项的地址去物理内存中获取,这就是一个页命中的流程。

3.3 缺页

有命中就有未命中,我们将未命中的访问称为缺页。
在这里插入图片描述CPU访问VP3,从有效位推断VP3存储在磁盘中,触发缺页异常。缺页异常调用内核的缺页异常处理程序,改程序会选择一个牺牲页,将VP3替换到牺牲页,此例中假设为VP4,如果VP4已经被修改,那么内核就会将它复制回磁盘并且修改PTE。完成这一系列操作,异常处理程序返回时,会重新启动导致缺页的指令,再次读取VP3,此时VP3指向的地址为DRAM。
磁盘和内存之间传送页的活动叫做交换或者页面调度。直到不命中发生时,才换入页面的这种策略称作按需页面调度。所有现代系统使用的基本都是按需页面调度的方式。

4 虚拟内存作为内存管理的工具

实际上,操作系统为每个进程提供了一个独立的页表,因而也就是一个独立的虚拟地址空间。
这样做的功能如下:
1)简化链接。独立的地址空间允许每个进程的内存映像使用相同的基本格式。例如Linux 64位地址空间,代码段总是从虚拟地址0x400000开始,数据段跟在代码段之后,栈占据用户进程地址空间最高的部分,并向下声张。这样的一致性简化了连接器的设计和实现。
2)简化加载。虚拟内存使得容易向内存中加载可视性文件和共享对象文件。加载器为代码段和数据段分配虚拟页,将PTE指向目标文件中适当的位置。将一组连续的虚拟页听射到任意一个文件中的任意位置的表示法称作内存映射。
3)简化共享。独立地址空间为操作系统提供了一个管理用户进程和操作系统自身共享的一致机制。
4)简化内存分配,虚拟内存为向用户进程提供一个简单地分配额外内存的机制。当一个用户进程要求额外的堆空间时,操作系统分配一个连续的虚拟地址空间,对应可能分散的物理地址空间。

5 虚拟内存作为内存保护的工具

现代计算机系统必须为操作系统提供手段来控制对内存系统的访问。比如,对只读内存的保护,进制对其他进程内存的访问等。
为了达成这样的目的,我们可以通过在PTE上添加一些额外的许可位来控制对一个虚拟页面内容的访问。
在这里插入图片描述
对于违反了这些许可条件的操作,那么CPU就触发故障,传递给内核的一个异常处理程序。Linux shell一般将这种异常报告为段错误segmentation fault。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值