虚拟内存管理

虚拟内存管理这是一种利用虚拟存储器来逻辑扩充物理内存的管理方式。其基本思想是用软硬件技术把内存与外存这两级存储器当成一级存储器来用,从而给用户提供了一个比内存也比任何应用程序大得多的虚拟存储器,使得用户编程时再也不用考虑内存大小的限制了,给用户编程带来极大的方便。

传统存储管理方式的特征

段页式的内存管理策略都是为了同时将多个进程保存在内存中以便允许多道程序设计。它们都具有以下两个共同的特征:

1)一次性:作业必须一次性全部装入内存后,方能开始运行。这会导致两种情况发生:①当作业很大,不能全部被装入内存时,将使该作业无法运行:②当大量作业要求运行时,由于内存不足以容纳所有作业,只能使少数作业先运行,导致多道程序度的下降。

2)驻留性:作业被装入内存后,就一直驻留在内存中,其任何部分都不会被换出,直至作业运行结束。运行中的进程,会因等待I/O而被阻塞,可能处于长期等待状态。

由以上分析可知,许多在程序运行中不用或暂时不用的程序(数据)占据了大量的内存空间,而一些需要运行的作业又无法装入运行,显然浪费了宝贵的内存资源。

局部性原理

局部性原理:指程序在执行过程中的一个较短时期内,所执行的指令地址和指令的操作数地址,分别局限于一定区域。

局部性主要表现:

时间局部性:是指一段指令在某一时间段内会被反复执行。即程序某一部分的数据或指令被重复性地访问,它们对应于程序结构中的循环、子程序、常用到的变量及数据等 ;

空间局部性:是指一旦某一个存储单元被访问,那么它附近的单元也将很快被访问。这对应于程序结构中的顺序执行的指令、线性数据结构以及在相邻位置存放的数据或变量等。而程序中的分支和调用子程序只是将程序的访问空间从一处移到另外一处,仍具有局部性。

排他性:程序运行不但体现在时间、空间的局部性,还体现在某些程序段执行的排他性。

即程序设计者编程时要考虑程序执行时所能遇到的各种情况,但具体到一次程序的执行,并不会发生所有的状况。因而某些程序段在进程整个运行期间,可能根本不使用,如出错处理、分支语句等。因而,没有用到的程序段就不必调入内存。另外,有些程序段仅执行一次,以后就再也不会用到,这样的程序段也没有必要一直占用内存空间。

综上所述:程序只要装入内存一部分就可以运行,当用到不在内存的部分时,再将其装入内存。换句话就是说程序全部装入内存并不是程序运行的必要条件。

虚拟内存的定义和特征

虚拟存储器

基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其余部分留在外存,就可以启动程序执行。在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换出到外存上,从而腾出空间存放将要调入内存的信息。这样,系统好像为用户提供了一个比实际内存大得多的存储器,称为虚拟存储器。

之所以将其称为虚拟存储器,是因为这种存储器实际上并不存在,只是由于系统提供了部分装入、请求调入和置换功能后(对用户完全透明),给用户的感觉是好像存在-一个比实际物理内存大得多的存储器.虚拟存储器的大小由计算机的地址结构决定,并非是内存和外存的简单相加。
虚拟存储器有以下三个主要特征:

  • 多次性,是指无需在作业运行时- 次性地全部装入内存,而是允许被分成多次调入内存运行。
  • 对换性,是指无需在作业运行时一直常驻内存,而是允许在作业的运行过程中,进行换进和换出。
  • 虚拟性,是指从逻辑上扩充内存的容量,使用户所看到的内存容量,远大于实际的内存容量。

虚拟内存的实现

虚拟内存中,允许将-一个作业分多次调入内存。采用连续分配方式时,会使相当一部分内存空间都处于暂时或“永久”的空闲状态,造成内存资源的严重浪费,而且也无法从逻辑上扩大内存容量。因此,虛拟内存的实现需要建立在离散分配的内存管理方式的基础上。

虚拟内存的实现有以下三种方式:

  • 请求分页存储管理。
  • 请求分段存储管理。
  • 请求段页式存储管理。

不管哪种方式,都需要有一-定的硬件支持。一般需要的支持有以下几个方面:

  • 一定容量的内存和外存。
  • 页表机制(或段表机制),作为主要的数据结构。
  • 中断机构,当用户程序要访问的部分尚未调入内存,则产生中断。
  • 地址变换机构,逻辑地址到物理地址的变换。

请求分页存储管理方式

为了实现请求分页,系统必须提供- -定的硬件支持。除了需要- -定容量的内存及外存的计算
机系统,还需要有页表机制、缺页中断机构和地址变换机构。

1.页表机制

请求分页系统的页表机制不同于基本分页系统,请求分页系统在.一个作业运行之前不要求全部一次性调入内存,因此在作业的运行过程中,必然会出现要访问的页面不在内存的情况,如何发现和处理这种情况是请求分页系统必须解决的两个基本问题。为此,在请求页表项中增加了四个字段。

增加的四个字段说明如下:

  • 状态位P:用于指示该页是否已调入内存,供程序访问时参考。
  • 访问字段A:用于记录本页在- 段时间内被访问的次数,或记录本页最近已有多长时间未被访问,供置换算法换出页面时参考。
  • 修改位M:标识该页在调入内存后是否被修改过。
  • 外存地址:用于指出该页在外存上的地址,通常是物理块号,供调入该页时参考。

2.缺页中断机构

在请求分页系统中,每当所要访问的页面不在内存时,便产生-一个缺页中断,请求操作系统将所缺的页调入内存。此时应将缺页的进程阻塞(调页完成唤醒),如果内存中有空闲块,则分配-一个块,将要调入的页装入该块,并修改页表中相应页表项,若此时内存中没有空闲块,则要淘汰某页(若被淘汰页在内存期间被修改过,则要将其写回外存)。

3.地址变换机构

请求分页系统中的地址变换机构,是在分页系统地址变换机构的基础上,为实现虚拟内存,又增加了某些功能而形成的。

                                                

页面置换算法

最佳置换算法(OPT)

方法:根据未来使用情况将未来的近期里不用的页替换出去。
实现:

  • 确定要替换的时刻T。
  • 找出主存中每个页将来要用到的时刻Ti。
  • Ti 减 T最大的页将被替换。

特点:命中率高,但难于实现(必须运行一遍,才能知道未来的时刻ti),是理想算法,用于评价其它替换算法。

                       

发生了6次页面置换,9次缺页中断,总访问次数20次,缺页率9/20=45% 。

先进先出(FIFO)页面置换算法

优先淘汰最早进入内存的页面,亦即在内存中驻留时间最久的页面。该算法实现简单,只需把调入内存的页面根据先后次序链接成队列,设置- 一个指针总指向最早的页面。但该算法与进程实际运行时的规律不适应,因为在进程中,有的页面经常被访问。

                        

发生了12次页面置换,15次缺页中断,总访问次数20次,缺页率15/20=75% 。

最近最久未使用(LRU)换算法

方法:近期最久未访问过的页作为被替换的页
实现:赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t,当须淘汰一个页面时,选择现有页面中其t值最大的页面予以淘汰。
特点:计数器硬件较少,主存页面表可由软硬件实现修改,根据“历史”预测“未来”。

                           

发生了9次页面置换,12次缺页中断,总访问次数20次,缺页率12/20=60% 。

LRU置换算法的硬件支持:

  • 每个页面设立移位寄存器:被访问时左边最高位置1,定期右移并且最高位补0,于是寄存器数值最小的是最久未使用页面。
  • 一个特殊的栈:把被访问的页面移到栈顶,于是栈底的是最久未使用页面。

Clock置换算法

每页设置一位访问位,若该页被访问则其访问位被置1;
内存中所有页面都通过链接指针链接成一个循环队列,置换时采用一个指针,从当前指针位置开始按地址先后检查各页,寻找访问位为0的页面作为被置换页;
指针经过的访问位为1的页都将其访问位置0,最后指针停留在被置换页的下一个页。

简单的Clock置换算法

                                                       

页面分配策略

駐留集大小

对于分页式的虚拟内存,在准备执行时,不需要也不可能把-.个进程的所有页都读取到主存,因此,操作系统必须决定读取多少页。也就是说,给特定的进程分配多大的主存空间,这需要考虑以下几点:

  1. 分配给一个进程的存储量越小,在任可时候驻留在主存中的进程数就越多,从而可以提高处理机的时间利用效率。
  2. 如果一个进程在主存中的页数过少,尽管有局部性原理,页错误率仍然会相对较高。
  3. 如果页数过多,由于局部性原理,给特定的进程分配更多的主存空间对该进程的错误率没有明显的影响。

固定分配、局部置换

  •  为每个进程分配固定页数的内存空间、且运行过程中不变。
  •  当进程缺页时,只能从该进程在内存的几个页面中选出一页换出,然后再调入一页,保证进程的页数不变。

可变分配、全局置换

  • 系统开始先为每个进程分配一定数目的物理块。整个系统有一空闲物理块链,当某进程缺页时,系统从空闲链中选出一块分配给进程。
  • 空闲链为空时,OS从所有进程的页面中权衡选择一页换出。

可变分配、局部置换

  • 分配同上,但进程缺页时,只能从该进程在内存的页面中选出一页换出。

调入页面的时机

为确定系统将进程运行时所缺的页面调入内存的时机,可采取以下两种调页策略:

(1)预调页策略。根据局部性原理,- -次调入若千个相邻的页可能会比一次调入- -页更高效。但如果调入的一批页面中大多数都未被访问,则又是低效的。所以就需要采用以预测为基础的预调页策略,将预计在不久之后便会被访问的页面预先调入内存。但目前预调页的成功率仅约50%。故这种策略主要用于进程的首次调入时,由程序员指出应该先调入哪些页。

(2)请求调页策略。进程在运行中需要访问的页面不在内存而提出请求,由系统将所需页面调入内存。由这种策略调入的页- -定会被访问, 且这种策略比较易于实现,故在目前的虚拟存储器中大多采用此策略。它的缺点在于每次只调入一页,调入调出页面数多时会花费过多的I/O开销。

预调入实际上就是运行前的调入,请求调页实际上就是运行期间调入。一般情况下,两种调页策略会同时使用。

从何处调入页面

请求分页系统中的外存分为两部分:用于存放文件的文件区和用于存放对换页面的对换区。对换区通常是采用连续分配方式,而文件区采用离散分配方式,故对换区的磁盘IO速度比文件区的更快。这样从何处调入页面有三种情况:

(1)系统拥有足够的对换区空间:可以全部从对换区调入所需页面,以提高调页速度。为此,在进程运行前,需将与该进程有关的文件从文件区复制到对换区。

(2)系统缺少足够的对换区空间:凡不会被修改的文件都直接从文件区调入;而当换出这些页面时,由于它们未被修改而不必再将它们换出。但对于那些可能被修改的部分,在将它们换出时须调到对换区,以后需要时再从对换区调入(这是因为读的速度比写的速度快)。

(3)UNIX方式:与进程有关的文件都放在文件区,故未运行过的页面,都应从文件区调入。曾经运行过但又被换出的页面,由于是被放在对换区,因此F次调入时应从对换区调入。进程请求的共享页面若被其他进程调入内存,则无需再从对换区调入。

抖动

在页面置换过程中的一种最糟糕的情形是,刚刚换出的页面马上又要换入主存,刚刚换入的页面马上就要换出主存,这种频繁的页面调度行为称为抖动,或颠簸。如果一个进程在换页 上用的时间多于执行时间,那么这个进程就在颠簸。

频繁的发生缺页中断(抖动), 其主要原因是某个进程频繁访问的页面数目高于可用的物理页帧数目。虚拟内存技术可以在内存中保留更多的进程以提高系统效率。在稳定状态,几乎主存的所有空间都被进程块占据,处理机和操作系统可以直接访问到尽可能多的进程。但如果管理不当,处理机的大部分时间都将用于交换块,即请求调入页面的操作,而不是执行进程的指令,这就会大大降低系统效率。

                                                

工作集

工作集(或驻留集)是指在某段时间间隔内,进程要访问的页面集合。经常被使用的页面需要在工作集中,而长期不被使用的页面要从工作集中被丢弃。为了防止系统出现抖动现象,需要选择合适的工作集大小。

工作集模型的原理是:让操作系统跟踪每个进程的工作集,并为进程分配大于其工作集的物理块。如果还有空闲物理块,则可以再调一个进程到内存以增加多道程序数。如果所有工作集之和增加以至于超过了可用物理块的总数,那么操作系统会暂停一个进程, 将其页面调出并且将其物理块分配给其他进程,防止出现抖动现象。

正确选择工作集的大小,对存储器的利用率和系统吞吐量的提高,都将产生重要影响。

最后总结

虚拟内存管理的优点:

  1. 主存利用率比较高:平均每个用户作业只浪费一半的页空间,内存规范易于管理。
  2. 对磁盘管理比较容易:因为页的大小一般取磁盘物理块大小的整数倍。
  3. 地址映射和变换的速度比较快:在把用户程序装入到主存储器的过程中,只要建立用户程序的虚页号与主存储器的实页号之间的对应关系即可(拼接得到物理地址),不必使用整个主存的地址长度,也不必考虑每页的长度等
  4. 大程序:可在较小的可用内存中执行较大的用户程序;
  5. 大的用户空间:提供给用户可用的虚拟内存空间通常大于物理内存(real memory)
  6. 并发:可在内存中容纳更多程序并发执行;
  7. 易于开发:与覆盖技术比较,不必影响编程时的程序结构

虚拟内存管理的缺点:

(1)程序的模块化性能不好。
由于用户程序是强制按照固定大小的页来划分的,而程序段的实际长度一般是不固定的。因此,虚拟页式存储器中一页通常不能表示一个完整的程序功能。一页可能只是一个程序段中的一部分,也可能在一页中包含了两个或两个以上程序段。
(2)页表很长,需要占用很大的存储空间。
通常,虚拟存储器中的每一页在页表中都要占一个页表项。假设有一个虚拟页式存储器,它的虚拟存储空间大小为4GB,每一页的大小为1KB,则页表的容量为4M(个页表项)。如果每个页表项占用4个字节,则页表的存储容量为16MB。

总结:总容量不超过物理内存和外存交换区容量之和。其运行速度接近于内存,每位的成本又接近于外存,是一种性能非常优越的存储管理技术。

 

可能有的小问题

1 虚拟内存管理发生在什么时候?

首先当cpu发出一个虚拟地址请求后,把虚拟地址送给MMU处理。

MMU得到地址后,通过计算得到页号/段号,先判断是否有读写权限,如果没有就返回错误,如果有再查询表(STL表/普通页表),

  • 如果表中没有该页/该段,就产生一个缺页中中断,虚拟内存管理技术就会通过一系列算法来把缺少的页从外存中取出来,放到内存中。
  • 如果表中有该页,那就通过表计算得到物理地址(即内存中的地址)。

CPU得到物理地址后就可以对内存进行读写操作。

2 为什么有时候多个的进程中有相同的虚拟地址,难道它们不会打架吗?

因为每个用户都有一份属于自己的页表,所以即使虚拟地址相同,但是对应的物理地址不同,即使物理地址相同,通过虚拟存储即使对内存中的某些页进行替换操作。

 

 

 

 

 

 

相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页