操作系统学习笔记 5虚拟内存
200 Words|Read in about 1 Min|本文总阅读量次
熟悉完操作系统的第四篇章,开始学习第五篇章,关于操作系统的虚拟内存。
0猜你喜欢
操作系统系列文章
5虚拟内存
虚拟内存的起因
-
覆盖技术
-
交换技术
-
虚存技术
目标
程序局部性原理
基本概念
基本特征
虚拟页式内存管理
5.1虚拟内存的起因
电子游戏的发展,从几百k到现在3D渲染越来越大,对计算机性能也会越来越高,需要更大内存更强机器才能让软件跑起来。程序规模的增长速度远大于存储容量的增长速度。因此,需要更多的程序跑在有限的内存里面。
5.2理想中的存储器
更大、更快、更便宜的非易失性存储器,但是实际的存储器如下图5-2所示。
5.3操作系统支持的存储器
可以看到在操作系统管理下的kernel,我们可以跑很多的程序,这些程序会占用内存空间。这些程序光是靠主存(物理内存)是不够的的。我们通过硬盘。把操作系统的一些管理数据放到硬盘中去,也别是一些不常用的数据,把常用的数据放到内存中,有限的内存可以放一些经常使用的代码和数据,通过这种方式可以实现虚拟大内存的技术。
5.4内存不够常用技术
- 如果是程序太大,超过了内存的容量,可以采用手动的覆盖技术。只把需要的指令和数据保存在内存中
- 如果是程序太多,超过了内存的容量,可以采用自动的交换技术,把暂时不能执行的程序送到外存中
- 如果想要在有限容量的内存中,以更小的页粒度为单位装入更多更大的程序,可以采用自动的虚拟存储技术。把程序内的一部分数据或者代码导入导出内存,基于分页、分段的硬件支持的方式,加上操作系统的管理就可以实现虚拟内存技术。
5.5覆盖技术
产生于上世纪80-90年代初的时候,特别是Dos程序,硬件是640K的内存,软件一般是几十K,大一点的是几M,需要虚拟出更大的空间让软件能够运行。
5.5.1目标
在较小的可用内存中运行较大的程序,常用于多道程序系统,与分区存储管理配合使用。
5.5.2原理
把程序按照其自身逻辑结构,划分为若干个功能上相互独立的程序模块,那些不会同时执行的模块共享同一块内存区域,按时间先后来运行。
- 必要部分(常用功能)的代码和数据常驻内存
- 可选部分(不常用功能)在其他程序模块中实现,平时存放在外存中,在需要用到时才装入内存
- 不存在调用关系的模块不必同时装入内存,从而可以相互覆盖,即这些模块共用一个分区
举例说明
有一个程序,有ABCDEF这六个函数组成,每个函数占用的程序空间不同,其中A函数会调用BC,B函数会调用D,C函数会调用EF。
其中A是常驻分区,他会调用其他的函数,BC函数因为不会相互调用所以分在同一个分区,DEF也会分到同一个分区。A调用到B之后,B就会记载到内存是50K,然后运行完B之后,就会把B数据拷贝到硬盘中,继续执行C,可以用覆盖区来存C,只占了30K,当A的代码和数据调到内存中后就可以调用C。
除了上述的覆盖方式,还存在其他的方式,需要的内存空间大小100K
这里的A占用一个分区20K
BEF公用一个分区50K
C和D公用一个分区30K
5.5.3覆盖技术缺点
- 有程序员来把一个大的程序划分为若干个小的功能模块,并确定各个模块之间的覆盖关系,费时费力,增加了编程的复杂度。
- 覆盖模块从外存装到内存,实际上是以时间延长来换取空间节省。
5.6交换技术
覆盖技术其实对程序和编程语音的要求比较高,增加了程序员开发的负担,随着硬件的发展和操作系统的增强,通过操作系统管理而不是程序员去管理。操作系统可以管理当前放哪个程序在内存中运行,对于暂时不能运行的程序可以导到硬盘中去。
5.6.1目标
多道程序在内存中时,让正在运行的程序或需要运行的程序获得更多的内存资源。
5.6.2方法
- 可将暂时不能运行的程序送到外存,从而获得空闲内存空间。
- 操作系统把一个进程的整个地址空间的内容保存到外存中(换出swap out),而将外存中的某个进程的地址空间读入到内存中(换入swap in)。换入换出内容的大小为整个程序的地址空间。
5.6.3交换技术实现问题
Q:交换时机的确定:何时需要发生交换?
A:只当内存空间不够或有不够的危险时换出
Q:交换区的大小确认
A:必须足够大以存放所有用户进程的所有内存映像的拷贝,必须能对这些内存映像进行直接存取。
Q:程序换入时的重定位实现,换出后在换入的内存位置一定要在原来的位置上吗
A:最好采用动态地址映射的方法,可能换出去的空间已经被占用。建立一个页表,虚地址一样,物理地址不一样,页表建立完成之后还是可以正常映射。修改页表的映射关系,重新映射物理地址。
5.6.4覆盖与交换比较
覆盖只能发生在那些相互之间没有调用关系的程序模块之间,因此程序员必须给出程序内的各个模块之间的逻辑覆盖结构。
交换技术是以在内存中的程序大小为单位来进行的,他不需要程序员给出各个模块之间的逻辑覆盖结构。换言之,交换发生在内存中程序与管理程序或操作系统之间,而覆盖则发生在运行程序的内部。
5.7 虚存技术
5.7.1目标
在内存不够用的情况下,可以采用覆盖技术和交换技术,但是覆盖技术和交换技术还存在一些缺点。技术上还达不到很方便、很高效的特点。解决方式是:虚拟内存管理技术(虚存技术)
-
覆盖技术
需要程序员自己把整个程序划分为若干个小的功能模块,并确认各个模块之间的覆盖关系,增加了程序员的负担
-
交换技术
以进程作为交换的单位,需要把进程的整个地址空间都换进换出,增加了处理器的开销。
1)像覆盖技术那样,不是把程序的所有内容都放在内存中,因而能够运行比当前的空闲内存空间还要大的程序。但做得更好,由操作系统自动来完成,无需程序员干涉。
2)像交换技术那样,能够实现进程在内存与外存之间的交换,因而获得更多的空闲内存空间。但做得更好,只对进程的部分内容在内存和外存之间进行交换。
如下图5-7-1所示,有四个程序。以P3为例,在内存中只需要两个内存页的数据,其他数据都是导入到硬盘里面。当前P3运行时,只会用到这两个页的数据,不会用到其他数据。虽然这个P3程序,整体运行需要很大内存,但是在某个有限段内的时间只需要一小段的内存。这种方式可以通过操作系统和MMU就可以做到。
5.7.2虚拟技术–程序的局部性原理
程序的局部性原理,指程序在执行过程中的一个较短时期,所执行的指令地址和指令的操作数地址,分别局限于一定区域。表现下面两个方面。
-
时间局部性
一条指令的一次执行和下次执行,一个数据的一次访问和下次访问都集中在一个较短时期内
-
空间局部性
当前指令和邻近的几条指令,当前访问的数据和邻近的几个数据都集中在一个较小的区域内
程序的局部性原理表明,从理论上来说,虚拟存储技术是能够实现的,而且在实现了以后应该是能够取得一个满意的效果的。
虚存技术–程序的局部性影响
解题思路如下所示
从
a[0][0]
到a[0][1023]
已经占了一个页(int是四个字节)。按照第一种方式,访问顺序是
a[0][0]
、a[1][0]
到a[1023][0]
,由于a[0][0]
、a[1][0]
在位置上差了4K的距离,访问到第二个的时候使得操作系统上不得不另一个4K数据块从硬盘导到内存中来可以访问,这个过程每一个访问下一个数据会发生一次的缺页中断,所以总共发生了1024*1024个缺页中断。第二种方式,访问顺序是
a[0][0]
、a[0][1]
到a[0][1023]
,其中a[0][0]
、a[0][1]
有很好的空间局部性,在一个循环中只会发生一次的缺页中断,所以总共发生1024次缺页中断。
5.7.3虚存技术的基本特征
-
大的用户空间
通过把物理内存和外存相结合,提供给用户的虚拟内存空间通常大于实际的物理内存,即实现了这两者的分离。如32位的虚拟地址理论上可以访问4GB,而可能计算机上仅有256M的物理内存,但硬盘容量大于4GB。
-
部分交换
与交换技术相比较,虚拟存储的调入和调出是对部分虚拟地址空间进行的
-
不连续性
物理内存分配的不连续,虚拟地址空间使用的不连续
5.7.4虚存技术–虚拟页式内存管理
以页为单位,页式内存管理做一个基础,阐述虚存技术的实现。
如下图5-7-2所示。左侧是逻辑地址空间,右侧是物理地址空间,左侧右侧以页为映射关系,依靠页表来维护映射关系。页表项的索引是页号,对应的内容是页帧号。页表中,除了页帧号之外,还有几个bit,其中有一个bit为代表存在或者不存在页帧号的标记,如果逻辑地址找不到对应映射的物理地址,会产生访问异常。
大部分虚拟存储系统都采用虚拟页式存储管理技术,即在页式存储管理的基础上,增加请求调页(需要这个页才把页调到这个内存中来)和页面置换(随着程序执行访问内存越来越多,某些不需要的页换出去,需要的页换进来)功能。
5.7.4.1基本思路
- 当一个用户程序要调入内存运行时,不是将该程序的所有页面都装入内存,而是只装入部分的页面,就可启动程序运行。
- 在运行的过程中,如果发现要运行的程序或要访问的数据不在内存,则向系统发出缺页中断请求,系统在处理这个中断时,将外存中对应的页面调入内存,使得该程序能够继续运行。
5.7.4.2页表表项
为了实现请求调页和页面置换,我们需要在页表表项增加一些bit位,用于丰富这些功能。
-
驻留位
之前就已经提到过,表示该页是在内存还是在外存。如果改为等于1,表示该页位于内存当中,即该页表项是有效的,可以使用;如果该位等于0,表示该页当前还在外存中,如果访问该页表项,将导致缺页中断
-
保护位
表示允许对该页做任何类型的访问,如只读、只写、可读写、可执行等
-
修改位
表明此页在内存中是否被修改过(写过)。当系统回收该物理页面时,根据此位来决定是否把它的内容写回外存
-
访问位
如果该页面被访问过(包括读操作或者写操作),则设置此位用于页面置换算法
如下图5-7-3所示,左边是虚存页表的映射关系,大小为64K,每一个页表项代表一个4K的物理页,这里的X代表驻留位为0,如果是具体的数驻留位则为1。
如果把虚拟的0地址赋给一个寄存器(MOV REG, 0 8192),找到0地址在页表中的位置,可以看到最底下那项显示为2,可以知道驻留位为1,且页帧号为2。页帧号乘以一个页大小4K,实际访问的物理地址是8K。
如果把32780的虚拟地址读到寄存器里面去(MOV REG, 32780),对应页表项为第8项,发现驻留位的为0,没有对应的页帧号,也意味着访问这一页会造成缺页异常。
5.7.4.3缺页中断
缺页中断处理过程
- 如果在内存中有空闲的物理页面,则分配一物理页帧f,然后转第4步,否则转第2步
- 采用某种页面置换算法,选择一个将被替换的物理页帧f,它所对应的逻辑页为q。如果该页在内存期间被修改过,则需把它会写外存。
- 对q所对应的页表项进行修改,把驻留位位置置为0
- 将需要访问的页p装入到物理页面f当中
- 修改p所对应的页表项的内容,把驻留位置为1,把物理页帧号置为f
- 重新运行被中断的指令
5.7.5后备存储
大量内存中的数据是放在外存中的,需要的时候才需要读进来,需要注意硬盘存储的特征,这里有好几种特殊的存储形式,来放置内存中所对应的数据和代码。为了保存未被映射的页,需要能够简单地识别在二级存储器中的页。
后备存储(二级存储)
交换空间(磁盘或者文件):特殊格式,用于存储未被映射的页面
- 一个虚拟地址空间的页面可以被映射到一个文件(在二级存储中)中的某个位置。类似访问一个数组,它是一个数据文件放置在硬盘上。当访问到一个地方,内存中找不到需要从数据文件中读出来
- 代码段:映射到可执行二进制文件
- 动态加载的共享库程序段:映射到动态调用的库文件。库也是放到相应的硬盘里面,需要的时候才会把库的代码数据读到内存中来
- 其他段:可能被映射到交换文件(swap file)。不同上面的文件形式存在,这里以分区的形式存在。程序在运行过程中,有可能产生很多数据,这些数据没有对应到上述的文件,它是一种动态产生的数据,可能这些数据会占用很大的空间,需要被换出到硬盘中去。操作系统会在硬盘中开辟一个区域,swap file,没有文件直接对应的内存的内容
5.7.6虚拟内存性能
有效存储器访问时间的计算
EAT = 10(1-p) + 5000000p(1+q),p为缺页的概率,q为页写操作的概率
其中10(1-q)为不缺页的概率的时间,5000000p缺页读操作(换进来),5000000pq缺页过程的时候需要写入操作(换出去)