目录
一.知识总览
二.覆盖技术
2.1覆盖技术简介
2.2覆盖技术基本思想
三.交换技术
3.1交换技术的基本思想
3.2交换技术的实现
3.3覆盖与交换的区别
四.虚拟存储技术
4.1虚拟内存的重要性
4.2虚拟内存的定义和特征
4.3虚拟内存的实现
4.3.1请求分页的虚拟内存中的页表机制
4.3.2请求分页中处理缺页的步骤
4.3.3请求缺页中完整的页表结构
4.3.4虚拟内存空间的大小
前文我们已经讲完了内存的分配与回收部分,我们今天来进入内存空间的扩充部分。
早期的计算机系统中,主存容量很小,虽然主存中仅存放一道用户程序,但是存储空间放不下用户进程的现象也经常发生。比如 IBM 推出的第一台PC机最大只支持 1MB 大小的内存。因此经常会出现内存大小不够的情况。后来人们引入了覆盖技术,用来解决“程序大小超过物理内存总和”的问题。
其基本思想:由于程序运行时并非任何时候都要访问程序及数据的各个部分(尤其是大程序),因此可以把用户空间分成一个固定区和若干个覆盖区。
将经常活跃的部分放在固定区,调入后就不再调出(除非运行结束,其余部分按调用关系分段。首先将那些即将要访问的段放入覆盖区,其他段放在外存中,在需要调用前,系统再将其调入覆盖区,替换覆盖区中原有的段。
举例:
1961年,英国曼切斯特研究人员提出一种自动执行overlay的方式。程序员自己管理主存,通过分解程序为小的覆盖区的方式执行程序。把地址空间和主存容量的概念区分开来。程序员在地址空间里编写程序,而程序则在真正的内存中运行。由一个专门的机制实现地址空间和实际主存之间的映射。
对于上述示例问题,将地址空间划分成4K大小的区间,装入内存的总是其中的一个区间;执行到某个区间时,把该区间的地址自动映射到0~4095之间,例如:4096→0, 4097 →1, ……, 8191 →4095。程序员在0~65535范围内写程序,完全不用管在多大的主存空间上执行,所以,这种方式对程序员来说,是透明的!
这个可寻址的地址空间是一种虚拟内存!
覆盖技术的特点是打破了必须将一个进程的全部信息装入主存后才能运行的限制,但当同时运行程序的代码量大于主存时仍不能运行。
当前这种技术已经过时。
进程的七态模型:
实现交换技术需要清楚怎么解决下面的问题:
1. 应该在外存(磁盘)的什么位置保存被换出的进程?
2. 什么时候应该交换?
无论是从增加多道程序的度,还是可能是程序员编写的进程太大而无法放入内存,都引出内存的大小限制了进程的执行。
通过实际程序的研究会发现,在许多情况下并不需要将整个程序置于内存中:程序通常具有处理异常错误条件的代码。由于这些错误很少实际发生,所以这些代码几乎从不执行。数组、列表和表等所分配的内存量通常多于实际需要值。按100×100个元素来声明的数组,可能实际很少用到大于10×10个的元素。程序的某些选项和功能可能很少使用。例如,程序的初始化操作。
执行只有部分处于内存的程序,可以带来许多好处:
程序不再受物理内存的可用量所限制。用户可以为一个巨大的虚拟地址空间(virtual-address space)编写程序,从而简化了编程任务。
由于每个用户程序可占用较少的物理内存,因此可以同时运行更多的程序,进而增加CPU利用率和吞吐量,但没有增加响应时间或周转时间。
将部分程序加载或交换到内存所需的I/O会更少,用户程序会运行得更快。
局部性原理:时间局部性 :如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环)空间局部性 :一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。 (因为很多数据在内存中都是连续存放的,并且程序的指令也是顺序地在内存中存放的)
页表中的有效-无效位方案
当该位被设置为“有效”时,相关联的页面是合法的,并且在内存中。当该位被设置为“无效”时,页面无效(即不在进程的逻辑地址空间中),或有效但只在辅助存储上。
对于已调入内存的页面,它的页表项是照常设置的;但是对于不在内存的页面,它的页表项可简单标记为无效。(请注意,如果进程从不尝试访问该页面,则将页面标记为无效并没有什么影响。)
其中逻辑内存中的第0块放在了物理内存中的4块,所以是有效的,有效位设置为有效。而逻辑地址中的第一块没有调入内存,所以可以简单的标记为无效。
而针对上图的问题,如果一个进程试图访问一个没有被带入内存的页面时,对标记为无效的页面访问会产生缺页错误(page fault)。分页硬件在通过页表转换地址时会注意到无效位被设置,从而陷入操作系统。这种陷阱是由于操作系统未能将所需的页面调入内存引起的。处理这种缺页错误的程序很简单。
1. 检查这个进程的内部表(通常与PCB (Process Control Block,进程控制块)一起保存),以确定该引用是有效的还是无效的内存访问。
2. 如果引用无效,那么终止进程。如果引用有效但是尚未调入页面,那么现在就应调入。
3. 找到一个空闲页框(例如,从空闲页框列表上得到一个)。
4. 调度一个辅助存储操作,以将所需页面读到刚分配的页框。
5. 当存储读取完成时,修改进程的内部表和页表,以指示该页现在处于内存中。
6. 重新启动被陷阱中断的指令。该进程现在能访问所需的页面,就好像它总是在内存中。
在4.3.1中,我们了解到请求缺页的虚拟内存中,相对于基本分页管理多了一个有效位。 但是我们还会面临以下问题:
根据完整的页表结构,我们再次分析缺页中断的处理:
在请求分页系统中,每当要访问的 页面不在内存 时,便产生一个 缺页中断 ,然后由操作系统的缺页 中断处理程序处理中断 。此时 缺页的进程阻塞 ,放入阻塞队列,调页 完成后再将其唤醒 ,放回就绪队列。如果内存中 有空闲块 ,则为进程 分配一个空闲块 ,将所缺页面装入该块,并修改页表中相应的页表项。如果内存中 没有空闲块 ,则 由 页面置换算法 选择一个页面淘汰 ,若该页面在内存期间 被修改过 ,则要将其 写回外存 。未修改过的页面不用写回外存。根据上述步骤分析上述例题:
- 观察所要访问的逻辑地址是否在内存中
- 不在内存中,就要从外存中调入内存
- 内存中有空闲a,所以直接调入
例如:
如:某计算机地址结构为 32 位,按字节编址,内存大小为 512MB ,外存大小为 2GB 。则虚拟内存的 最大容量 为 2 32 B = 4GB虚拟内存的 实际容量 = min (2 32 B, 512MB+2GB) = 2GB+512MB