在没有虚拟存储器之前
源程序在gcc –o 后生成的文件是可执行目标程序a.out,每条指令都有一个逻辑地址 32位。它存在硬盘上。
要执行时,只需找到该文件,将其装入内存。
装入的方式可以有多种,比如分页,分段等等。但是,必须将该程序完全装入内存。
分页:将一个进程的逻辑地址空间(32位)分成若干大小相等的页。
使用分页方式时有一个问题,必须清楚:
os是根据文件系统找到的a.out,跟a.out的逻辑地址没有一点关系
假如a.out是3个页大小,
就将这3个页分别装入内存,
装入内存的过程中将逻辑地址转换为物理地址。
如果内存为1G 每个程序的大小是100M,那么该os最多只能装10个程序。
虚拟存储器的定义:
具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储系统。
即,程序在运行之前,没必要全部装入内存,
仅把当前要运行的页装入即可,当程序运行时,如果需要其它页面,再进行页面调入或者置换。
这样 假如内存为1G,硬盘为200G,每个程序的大小为2G。
那么该os可以同时装100个程序进内存(甚至可以更多,此处是100,是因为硬盘大小的限制)。而此前的os一个程序也装不下。
也就是说,在用户看来,内存的容量变为了200G,因为有100个2G的程序被装入内存了。
但实际的内存只有1G,因此将这种存储系统称为虚拟存储器。
接下来的问题是,在没有虚拟存储器之前,os根据文件名通过文件系统将程序的全部内容载入内存,现在仅装入了一部分,剩下的部分在需要时os该怎么找到?
每个进程都有一张页表。页表的作用是实现程序页号到实地址块号的映射。页表是放在内存中的。
请求分页系统的页表项:
页号 |
实地址块号 |
状态位 |
修改位 |
外存地址 |
这样os就可以根据外存地址将所需的页面从硬盘中找到装入对应的内存中了。
综上,逻辑地址跟硬盘一点关系都没有。
逻辑地址使每个进程可以独立对程序的指令进行了编号,这样使每个进程都感觉自己在独占内存。到执行的时候容易将其映射为物理地址。
虚拟存储器的引入 使程序可以不必完全装入内存就能运行。
虚拟存储器一般会用到分页、分段,
但是,分页、分段并不是因为虚拟存储器才被发明的。
明白了这些以后,虚拟内存就比较好理解了
虚拟内存是用硬盘的一部分当内存,虽然把它当做内存用,可这块空间毕竟是在硬盘,速度肯定不如真是内存,所以说它是虚的。
这块虚拟内存的主要用途是当真实的内存被用完以后,又发生页面置换时,可以先把该页面换到这个地方。即虽然页面被换出内存了,但认为其还在内存。这个地方可以被称为假的实地址。
这块硬盘采用的调度算法和其他地方不一样。它是专门为换入换出设计的。
在32位系统中,假如物理内存大于4G,虚拟内存将完全无用武之地。因为cpu只能访问4G的内存空间,没必要再用硬盘当内存了。