虚拟内存

扶醉桌前 提交于 2019-11-27 16:08:28

首先先了解下计算机的存储结构:

 虚拟内存是借助二级存储空间来扩大一级存储空间的机制。

DRAM是VM系统(虚拟存储器系统)在主存中的缓存,他在主存中用在缓存虚拟页。

SRAM是CPU和主存之间的高速缓冲,CPU从主存中取指。

CPU先在SRAM中查找,如果不命中,则在DRAM中查找,如果再次查找失败,则通过页面置换,从磁盘中读取数据。由于IO操作开销很大,所以DRAM命中失败的开销更大。当CPU需要从磁盘中查找DRAM未命中的数据时,需要借助MMU(内存管理单元)来获取数据在磁盘中的位置,MMU完成物理地址到虚拟地址的转换,数据在磁盘中的地址就是虚拟地址。

数据一般按页存储,一个页面一般是4~8KB。

虚拟地址(VA),假设其范围是[0,1,2......N-1],N=2^n,N的单位为字节,那么这个虚拟地址就叫做一个n位地址空间。32/64位操作系统具有的虚拟内存空间大小分别是2^32和2^64。

虚拟存储器(VM)就是一个存储在磁盘上的N个连续字节大小的单元。每个字节都是一个唯一的虚拟内存地址。操作系统将VM分割成虚拟页大小的块。

物理存储器被分割成物理页(PP),大小也为字节。

虚拟页(VP)有三种状态:

1)未分配虚拟页:在页表中不存在对该虚拟页的记录;

2)已缓存虚拟页:在页表中有记录,且在物理存储器中已经分配了页面;

3)未缓存虚拟页:在页表中有记录,但是没有缓存到物理存储器。

我认为这里的物理存储器就是DRAM。

上面提到了页表,页表是存储在DRAM中的一个数据结构,完成虚拟页到物理页的映射。虚拟存储器/页表/物理存储器之间的映射关系如下:

 图中,页表记录了虚拟页VP1,VP2,VP7,VP4在物理存储器中的位置,VP3,VP6在页表中有记录,但是没有缓存到物理存储器。有效位用来记录页表是否缓存到物理存储器。进程被分配的内存都是虚拟内存,当CPU读取进程的数据时,其实就是获取虚拟页的数据的过程,CPU首先通过虚拟地址作为页表的下标索引,找到其在页表中的记录,通过记录获取它在物理存储器中的物理地址,然后读取物理页。

CPU在DRAM中命中失败,叫做缺页。缺页后的一种算法是按需调度算法:

1.从DRAM中选择一个牺牲页;

2.如果牺牲页被修改过,则将其拷贝回磁盘;

3.根据虚拟地址,通过IO操作从磁盘中获取虚拟页,将其拷贝到DRAM中,并更新页表。

磁盘与DRAM之间的页面交换行为叫做页面调度。

程序的时间局部性使得虚拟存储的概念非常好用,所谓的程序时间局部性是指,在某一段时间,程序趋向于重复执行某一段代码。这种特性使得频繁的页面调度不会出现。

每一个进程都有自己独立的虚拟内存空间,多个虚拟页表可以映射到同一物理页面上,具体某一时刻该哪一进程调用,属于系统资源调度问题,分时系统采用时间分片的方式,具体的调度算法在后面的章节中讲述。

每个进程都有相同格式的内存分配,不管代码和数据实际存储在物理存储器的何处,每个linux进程都使用如下格式:

虚拟地址空间从0x0000 0000-0xffff ffff,大致前3G(0x0000 0000-0xbfff ffff)是用户空间,后1G(0xc000 0000-0xffff ffff)是内核空间,只读段存储的应该是程序二进制代码以及文字常量,然后是.data,存储的是已初始化的全局变量,然后再是.bss,存储的是未初始化的全局变量,然后再是堆区,是程序员通过malloc/new来分配内存的地方,通过链表的方式分配内存(堆的分配算法会在后面讲到),从低地址向高地址分配,不连续;再是共享库的存储器映射区域;再是栈区,用来存储函数的参数以及局部变量,从高地址向低地址连续分配;再是用户栈,存储的是命令行参数和环境变量。

操作系统会为进程分配连续的虚拟地址,但是映射到的物理地址并不连续。

虚拟内存的优缺点:

优点

1.虚拟内存机制使得对磁盘的访问得以控制,因为进程被分配的虚拟空间,有区域是只读,有的区域是可读可写,有的区域是不能访问,原本磁盘的访问是任意的,现在编程可控的。

2.虚拟内存机制可以使得进程拥有自己连续独立的空间,进程之间互不干扰。

3.使用有限资源,处理比实际内存更大的文件;

缺点

如果内存严重不足。会引起内存与磁盘的频繁切换,降低性能。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!