程序大小的增长速度比内存容量的增长速度要快的多。讨论操作系统如何创建抽象模型以及怎样管理他们的。
分层存储器体系实现一个私有的,容量无限大的,速度无线快的永久性的存储器。
OS中管理分层存储器体系的部分称为存储管理器。他的任务是有效管理内存,即记录哪些内存是正在使用的,哪些内存是空闲的;在进程需要时为其分配内存,在进程使用完后释放内存。
最简单的存储器抽象就是没有存储器抽象,每一个程序都直接访问物理内存。
这种情况下,想要在内存中同时运行两个程序是不可能的,一个程序会擦除另一个程序在相同位置的所有内容。
可选项:
按这种方式组织系统时,任意时刻只有一个进程在运行。一旦用户键入了一个命令,操作系统需要把需要的程序从磁盘复制到内存中,并执行。当进程运行结束后,操作系统在用户终端显示提示符并等待新的命令,收到新的命令后,覆盖上一个程序。
再没有存储器抽象的系统中实现并行的另一种方式是使用多线程来进行编程。
运行的进程如果需要访问==保护键==与其PSW码不同的内存,360的硬件会捕获到这一事件。只有操作系统可以修改保护键,这样就可以防止用户进程之间、用户进程与操作系统之间的互相干扰。
但是需要避免程序使用绝对地址的问题,可以用静态重定位的技术来修正:程序被装载时修改其中的地址。
编译后产生绝对地址,只用于单道程序。
装入时对地址进行重定位,将逻辑地址转换为物理地址。
问题:运行期间不可再移动,需要地址上连续的物理内存。
动态运行时装入,装入模块装入后不会立即转换,程序执行时转换,需要维护重定位寄存器。
重定位寄存器
{
基址寄存器
界限寄存器
重定位寄存器
把物理地址暴露给进程会带来严重的问题:
要使多个程序同时处于内存中并且互不影响,需要解决两个问题:保护和重定位。
原始的解决方法:
更好的解决方法:
创建新的存储器抽象,地址空间。地址空间是可以用来寻址内存的一套地址集合。
比较难的是给每个程序一个自己独有的地址空间,使得一个程序中的地址28对应的物理地址与另一个程序中的地址28对应的物理地址不同。
使用动态重定位技术。给CPU配置两个特殊的硬件寄存器:基址寄存器和界限寄存器。
使用基址寄存器和界限寄存器时,程序装载到连续的空闲位置且装在期间无需重定位。
当程序运行时,程序的起始地址加载到基址寄存器中,程序的长度装载到界限寄存器中。
每次进程访问内存,取出一条指令,读或者写一个数据字,CPU会把地址发送到内存总线前,自动把基址加到进程发出的地址上。同时检查程序提供的地址是否大于界限寄存器里的值。如果访问的地址超过了界限,会产生错误,并且停止访问。
处理内存超载的方法:
{
交换技术
虚拟内存
交换技术:
程序换入换出需要使用界限寄存器。
可能出现内存空洞:需要内存紧缩。
使用动态内存时,必须对其进行管理。跟踪内存的使用情况:
0表示空闲,1表示占用。
当按照地址顺序在链表中存放进程和空闲区时,有几种算法可以为创建的进程分配内存。
软件的膨胀:超过了存储器的大小。
20世纪60年代所采取的方法是:把程序分割成许多片段,称为覆盖。
程序开始时,覆盖管理模块装入内存,该管理模块立即装入并运行覆盖0。执行完后覆盖0通知管理模块装入覆盖1,或者允许占用覆盖0上方的位置,或者占用覆盖0。一些覆盖系统非常复杂,允许多个覆盖同时在内存中。覆盖块存放在磁盘上,在需要时由操作系统动态的换入换出。
覆盖技术的思想:程序分段
{
常用段
:
常驻内存
不常用段
:
load in core when needed
划分内存为一个固定区和若干个覆盖区。
虚拟内存的基本思想:每个程序有自己的地址空间,这个空间被划分为多个块,每一块称为一页或页面(page)。每一页有连续的地址范围。这些页被映射到物理内存,但并不是所有的页都必须在内存中才能运行程序。当程序引用到一部分在物理内存中的地址空间时,由硬件立即执行必要的映射。当程序引用到一部分不在物理内存中的地址时,由操作系统负责将缺失的部分装入物理内存并且重新执行失败的指令。
从某种角度来讲,虚拟内存是对基址寄存器和界限寄存器的一种综合。
大部分虚拟内存使用分页技术(paging)。
程序执行指令MOV REG, 1000,把地址为1000的内存单元的内容复制到REG中。地址可以通过索引、段址寄存器、基址寄存器或者其他方式产生。
由程序产生的地址为虚拟地址,它们构成了一个虚拟地址空间。
虚拟地址空间按照固定大小分为被称为页面(page)的若干单元。在物理内存中对应的单元称为页框(page frame)。页面和页框的大小通常是一样的。
RAM和磁盘之间的交换总是以一个页面为单元进行的。实际的硬件中用一个“在/不在”位记录页面在内存中的实际存在情况。
缺页中断:MMU注意到程序引用了一部分不在物理内存中的地址,于是CPU陷入到操作系统,这个陷阱称为缺页中断或者缺页错误。找到一个很少使用的页框并把它写入磁盘,随后把需要访问的页面读到刚才收回的页框中,修改映射关系,然后重新启动引起陷阱的指令。
页表:索引,得到虚拟页框的框号。
虚拟地址被分为虚拟页号和偏移量两部分。
不同计算机的页表项大小可能不一样,但是32位是一个常用的大小。
最重要的就是页框号。
其次是“在/不在”位。这一位是1时,表示可以使用;如果是0,访问该页面会引起一个缺页中断。
允许什么类型的访问:0表示读/写,1表示只读
重新分配页框时十分有用。如果一个页面已经被修改过,那么必须把他写回磁盘。如果一个页面没有被修改过,那么只需要简单的将其丢弃。
它的值适合用来帮助操作系统在发生缺页中断时选择要淘汰的页面。不再使用的页面要比正在使用的页面更适合淘汰。
分页系统中的两个问题:
程序的局部性原理。使用转换检测缓冲区或者相联存储器或快表实现。通常在MMU中,包含少量的页表项。每个表项记录了一个页面的相关信息,包括虚拟页号、页面的修改位、保护码(读/写/执行)和该页对应的物理页框。
TLB工作原理:
将一个虚拟地址放入MMU中进行转换时,硬件首先通过将该虚拟页号与TLB中的所有表项进行对比,判断虚拟页面是否在其中,如果发现了一个有效的匹配并且要进行的访问操作不违法保护位,那么将页框号直接从TLB取出,而不必再访问页表。如果虚拟页号确实是在TLB中,但指令试图在一个只读页面上进行写操作,则会产生一个保护错误,就像对页表进行非法访问一样。
TLB失效:
现代机器当TLB失效时,并不是由MMU访问页表查找并取出所需的页表项,而是生成一个TLB失效,并将问题交给操作系统解决。系统必须先找到这个页面,然后从TLB中删除一项,接着装载一个新的项,最后再执行先前的出错的命令。
多级页表;倒排页表;
当发生缺页中断时,操作系统必须在内存中选择一个页面将其换出去,以便为调入的页面腾出空间。如果要换出的页面在内存驻留期间已经被修改过,就必须把它写回磁盘以更新它在磁盘上的副本;如果该页面没有被修改过,那么不需要回写。