第三章 内存管理 虚拟内存管理

原文地址:第三章 内存管理——王道操作系统 – Beatless

目录

二、虚拟内存管理

虚拟内存的基本概念

请求分页管理方式

页框分配

页面置换算法

抖动和工作集

内存映射文件

虚拟存储器性能影响


二、虚拟内存管理

虚拟内存的基本概念

1、传统存储方式的特征

(1)一次性:作业必须一次性装入内存后,才能开始运行。

导致的问题:
① 当作业很大而不能全部被装入内存时,将使该作业无法运行;
② 当大量作业要求运行时,由于内存有限,只能让少数作业运行,导致多道程序并发性下降。

(2)驻留性:作业被装入内存后,一直驻留在内存里,除非运行结束,请求IO操作会导致阻塞,可能长期处于等待状态。

2、局部性原理

(1)时间局部性(2)空间局部性

广义上来说,快表、页高速缓存及虚拟内存技术都属于高速缓存技术,而它依赖于局部性原理。

虚拟内存技术实际上建立了“内存-外存”的两级存储器结构,利用局部性原理实现高速缓存技术。

3、虚拟存储器的定义和特征

请求调页(请求调段):当想要访问的页面(段)不在内存中时,由操作系统负责将所需要的信息从外存调入内存,然后继续执行程序。

页面置换(段置换):当内存空间不够时,由操作系统负责将内存中暂时不用的信息换到外存。

部分装入:在程序装入时,仅需要将程序当前运行要用到的少数页面(段)装入内存,而将其余部分暂留在外存,便可以启动程序执行。

请求调页、页面置换和部分装入都是对用户透明的。

虚拟存储器的特征:
(1)多次性:无需在作业运行时一次性全部装入内存,而是允许被分成多次调入内存。即只需将当前运行的那部分程序和数据装入内存即可运行。
(2)对换性:作业运行过程中,将暂时不使用的程序和数据调到外存中(换出)。
(3)虚拟性:从逻辑上扩充了内存容量,使用户看到的远大于实际的内存容量。

4、虚拟内存技术的实现

若采用连续内存分配方式,会使相当一部分内存空间处于”暂时“或”永久“空闲状态,造成内存资源的严重浪费,一次虚拟内存技术的实现建立在离散分配方式之上。

实现方式:① 请求分页存储管理;② 请求分段存储管理;③ 请求段页式存储管理

不论哪种实现方式都需要一定的硬件支持:
(1)一定的内存和外存;
(2)页表或段表机制作为主要的数据结构;
(3)中断机构,当前用户程序要访问的部分尚未调入内存,产生缺页中断;
(4)地址变换机构,将CPU生成的逻辑地址映射到物理地址。

请求分页管理方式

请求分页管理方式建立在基本分页系统的基础之上,为支持虚拟存储器功能而增加了请求调页和页面置换功能,包含页表机制、缺页中断机制、地址变换机构。

1、页表机制

基本页表项:页号、物理块号。
请求分页的页表项:页号、物理块号、状态位、访问字段、修改位、外存地址。

状态位P:表示当前页面是否在内存中,若在则为1,若不在则为0。
访问字段A:表示近一段时间内该页面被访问的次数,或记录本页最近已有多长时间未被访问。
修改位M:表示当前页面在调入后是否被修改过,以决定换出时是否写回外存。
外存地址:记录该页在外存中的存放地址,通常是物理块号,供调入页面时参考。

2、缺页中断机制

在请求分页系统中,每当要访问的页面不在内存中的时候,便产生一个缺页中断,然后由OS的缺页中断处理程序处理。此时缺页的进程被阻塞,放入阻塞队列,当调页完成后唤醒并放回就绪队列。

缺页中断处理过程:
(1)若内存中由空闲块,则为进程分配一个空闲块,将缺的页面装入,并修改页表中相应的页表项。
(2)若内存中没有空闲块,则有页面置换算法选择一个页面淘汰,若该页面在内存期间被修改过,则要将被淘汰的页面写回外存。

缺页中断是一种内部异常(内中断),使故障(Fault)的一种,处理过程:
保护CPU环境(CPU上下文)-> 分析中断原因(查中断向量表)-> 转入中断处理程序 -> 恢复CPU环境

缺页中断与一般中断的区别:
(1)在指令执行期间而非一条指令执行完后产生和处理中断,属于内部异常(内中断)。
(2)一条指令在执行期间,可能产生多次缺页中断,如:copy A to B。

3、地址变换机构

在基本分页地址变换机构的基础上,增加了产生和处理缺页中断,及从内存中换出一页的功能。

变换过程:
① 检索快表,若命中,则取出物理块号,并修改访问字段A,若该指令是写指令,还要修改修改位M;
② 若快表未命中,则查找页表,若找到,取出物理块号,并将页表项写入快表,修改访问字段A和修改位M,若快表已满,则采用算法替换一项。
③ 若页表中该页未在内存中,则进行缺页中断处理,将该页调入内存,更新快表和页表,获取物理块号。
④ 利用物理块号和页内地址拼接成物理地址,访存。

(1)页不在内存中,产生缺页中断,请求调页;
(2)缺页中断处理的第一步就是要保存CPU上下文;
(3)内存已满选择一页换出,与页面置换算法有关;
(4)缓入/换出操作都需要启动慢速的IO操作,如果换入/换出太过频繁,系统开销会很大。
(5)页面调入内存后,需要修改慢表,并将表项复制到快表。

页框分配

1、驻留集

驻留集的概念:给一个进程分配的页框集合。

对于分页式的虚拟内存,在进程准备执行的时候,不需要也不可能将一个进程的所有页都读入主存。因此,由操作系统来决定读取多少页,即决定给特定的进程分配几个页框。

(1)驻留集小:驻留在内存中的进程多,程序并发性好,但分配给每个进程的页框太少,会导致缺页率过高,耗费大量CPU时间来处理缺页。

(2)驻留集大:分配给进程的页框超过某一个数目的时候,再为进程增加页框对缺页率的改善不明显,反而导致浪费内存空间,多道程序并发度下降。

2、内存分配策略

分页采取的内存分配策略:① 固定分配策略 ② 可变分配策略
置换采取的内存分配策略:① 全局置换 ② 局部置换

(1)固定分配局部置换

思想:为每个进程分配固定数目的物理块(页框),在进程运行期间不改变(固定分配)。若进程发生缺页,只能选该进程在内存中的一页并换出,然后调入一页(局部置换)。

缺点:难以确定为每个进程分配的物理块数目,太少会导致频繁发生缺页中断,太多又会降低CPU和其他资源的利用率。

(2)可变分配全局置换

思想:先为每个进程分配一定数目的物理块,并在程序运行期间根据情况适当的增加或减少。进程若发生缺页,则从系统空闲物理块队列中取出一块并分配给进程,并将缺页调入(全局置换)。

优点:比固定分配局部置换更加灵活,可以动态地增加进程的物理块。

缺点:会盲目地给进程增加物理块,导致多道程序并发度下降。

(3)可变分配局部置换

思想:为每个进程分配一定数目的物理块,当某进程发生缺页时,只允许从该进程的内存页面中选出一页换出。若频繁发生缺页,系统再为其分配若干物理块;若缺页率很低,则适当减少分配给该进程的物理块。

优点:保证进程不会过多调页的同时,也保持了多道程序的并发能力。

缺点:需要更复杂的实现,也需要更大的开销。

3、物理块调入算法

采用固定分配策略时,将系统中的空闲物理块分配给各进程的算法:
(1)平均分配算法:将系统中可供分配的物理块平均分配给各进程。
(2)按比例分配算法:根据进程大小按比例分配物理块。
(3)优先权分配算法:为紧迫的进程分配更多的物理块。实现方式:将可供分配的物理块分为两个部分,一部分平均分配,另一部分按优先级分配。

4、调入页面的时机

采用两种调页策略:① 预调页策略;② 请求调页策略

(1)预调页策略:一次调入若干个相邻的页面。

调页时机:主要用于进程的首次调入,由程序员指定调入哪些页面。

(2)请求调页策略:一次仅调入一个页面

调页时机:进程运行过程中,需要访问的页面不存在,提出调页请求(缺页中断)。

虚拟机存储器大多采用这种策略,但是由于一次只能调入一个页面,因此增加了磁盘的开销。

注意:预调页策略是在运行前的调入,请求调页策略是在运行期间的调入。预调页策略一次性调入的若干相邻的页不一定都能用得上,此时它是低效的,因此不适用于进程中。

5、从何处调页

(1)拥有足够内存空间(进程比较少):全部从对换区调入所需页面,以提高调页速度。为此,需要提前将与该进程的有关文件复制到对换区。

(2)缺少足够内存空间(进程比较多):不会被修改的文件都直接从文件区调入,换出时不需要再写回外存;可能被修改的换出时放在对换区,需要时再从对换区调入。

(3)UNIX方式:与进程有关的文件放在文件区,未运行过的页面都从文件区调入,运行过的由于存放在对换区,从对换区调入。

6、如何调入页面

当进程所访问的页面不在内存中时(状态位/存在位 = 0),便向CPU发出调页请求(缺页中断),中断响应后执行缺页中断处理程序。

(1)若内存未满,启动磁盘IO程序,将缺页调入内存,并修改页表项;
(2)若内存已满,按置换算法选择一页准备换出:若该页未被修改过(修改位 = 0),则不用写回外存;若该页被修改过(修改位 = 1),则需要写回外存。

换出后,将缺页调入内存,并修改相应的页表项,将其状态位/存在位置为1,有快表的话,同时修改快表项。

页面置换算法

处理缺页中断的时候,若内存已满,则需要选择一个页面并将其换出,将选择页面的算法称为页面置换算法。页面置换算法需要启动磁盘IO,因此开销较大,一个好的页面置换算法应追求低缺页率。

常见的几种页面置换算法:最佳置换算法(OPT)、先进先出置换算法(FIFO)、最近最久未使用算法(LRU)、时钟置换算法(CLOCK)。

1、最佳(OPT)置换算法

思想:选择淘汰的页面是以后永久不使用的,或是在最长时间内不再被访问的页面(区别于,以后访问次数最少),以便获得最低的缺页率。

注:该算法无法实现,但可以利用该算法去评价其他算法。

2、先进先出(FIFO)置换算法(基于队列实现)

思想:FIFO选择淘汰的页面是最早进入内存的页面。将内存的页面根据调入的先后顺序排成一个队列,换出时选择队首的页面换出。

评价:
(1)该算法没有利用局部性原理,与进程实际运行的规律不适应,因此性能较差。
(2)FIFO算法还会产生为当前进程分配的物理块增多,缺页次数不减反增的异常现象,这种现象称为Belady异常。
(3)只有FIFO会出现Belady异常,而OPT和LRU算法都不会。

3、最近最久未使用(LRU)算法(基于栈实现,需要寄存器和栈的硬件支持)

思想:LRU算法淘汰的是最近最长时间未使用的页面,它认为过去一段时间未访问过的页面,在最近的将来也不会被访问。

评价:
(1)LRU算法性能接近OPT算法,但实现起来开销较大——需要寄存器和硬件支持。
(2)LRU算法属于堆栈类算法,不会出现Belady异常。

4、时钟(CLOCK)置换算法

(1)简单的CLOCK置换算法(NRU算法)

换出页面步骤:

  • 为每个页面设置一位访问位,当某页首次被装入或被访问时,其访问位设为1;
  • 算法将内存中的每个页面链接成一个循环队列,并有一个替换指针与之相关联;
  • 当某一页被替换时,该指针被设置为指向被替换页面的下一页;
  • 在选择淘汰一页时,只需要检查页面的访问位:
    • 若为0,就选择该页换出;
    • 若为1,置为0,暂不换出,依次顺序检查下一个页面的访问位。

因为该算法只有一位访问位,二至还是将未使用过的页面患处,所以也称最近未用(NRU)置换算法。

(2)改进型CLOCK置换算法

建一个页面换出时,若该页面被修改过,则需要将该页写回磁盘。对于修改后的页面,替换代价更大。在改进型CLOCK置换算法中,除了考虑页面使用情况外,还增加了置换代价——修改位。

由访问位A与修改位M可以组成下列四种页面(换出优先级从高到低):
1类:A = 0, M = 0;2类:A = 0, M = 1;3类:A = 1, M = 0;4类:A = 1, M = 1

算法执行过程:
Ⅰ. 从当前指针开始,扫描循环队列,寻找1类页面作为换出页;
Ⅱ. 若Ⅰ失败,则循环第二遍,寻找2类页面作为换出页,扫描过的页面访问位置为0;
Ⅲ. 若Ⅱ失败,则重新执行Ⅰ、Ⅱ。

注:在Ⅱ之后会将3、4类变为1、2类。

改进型CLOCK置换算法优于简单的CLOCK置换算法的地方在于,可以减少磁盘IO操作的次数。但是为了找到一个可以用于交换的页面,可能要经过几轮的扫描,即实现算法本身的开销将有所增加。

抖动和工作集

1、抖动

抖动:刚刚换出的页面马上又要换入内存,或相反,这种频繁的页面调度行为称为抖动或颠簸,

驻留集:给一个进程分配的页框集合(物理块/内存块集合)

发生的根本原因:分配给每个进程的物理块太少,不能满足进程的正常运行的基本要求。

抖动发生的后果:进程对磁盘的访问速度急剧增加,使每个进程的多数时间都用于页面的换入/换出,几乎不可能做任何有效的工作,进而导致发生CPU利用率急剧下降并趋近于0的情况。

2、工作集

工作集:指在某个时间间隔内,进程想要访问的页面集合。工作集可由时间和工作集窗口尺寸确定。

例如,某个进程对页面的访问次序如下,工作集窗口尺寸 = 5

t1时刻,进程的工作集为{2,3,5};t2时刻,进程的工作集为{1,2,3,4}。

工作集窗口:一个大小固定的滑块。
工作集:滑块内的页面集合。
驻留集:给一个进程分配的页框集合。

实际应用种,工作集窗口会设置地很大,但对于局部性好的程序,工作集大小会比工作集窗口小很多。工作集反映了进程在接下来一段时间内很有可能会频繁访问的页面集合。

驻留集大小不能小于工作集,否则进程在运行过程中会频繁出现缺页。

内存映射文件

内存映射文件(Memory-Mapped Files):在磁盘文件与进程的虚拟地址空间之间建立映射关系,是操作系统提供给上层应用程序的一个系统调用。

作用:
(1)方便程序员访问文件数据;
(2)方便多个进程共享同一个文件。

传统文件的访问方式:
(1)open系统调用:打开文件;
(2)seek系统调用:将读写指针移动到某个位置;
(3)read系统调用:从读写指针所指的位置,读入若干数据(从磁盘读入内存);
(4)wirte系统调用:见内存中指定的数据写回磁盘(根据读写指针确定要写回哪里)。

内存映射文件的方式:
(1)open系统调用:打开文件;
(2)mmap系统调用:将文件映射到进程的虚拟地址空间。
(2->1)以访问内存的方式访问文件数据;
(2->2)文件数据的读入、写出由操作系统自动完成;
(2->3)进程关闭文件时,操作系统自动将文件被修改的数据写回磁盘。
(3)close系统调用:关闭文件。

打开文件后,调用mmap返回映射区的起始地址*start,将*start加上一个长度用来访问该映射区,若*p指向的块不在内存中,则产生缺页中断,有缺页中断处理程序完成页面调用,然后访问。

进程通过mmap系统调用,将一个文件映射到其虚拟地址空间中的某个区域,之后用访问内存的方式来读写该文件。

特点:
(1)它将文件当作内存中的一个大字符数组来访问,而不通过文件IO操作来访问,更方便。
(2)磁盘文件的读出/写入由操作系统完成,对进程而言是透明的。
(3)当映射页面时,不会实际读入文件内容,而只在访问页面的时候才被一次一页地读入。
(4)当进程退出或关闭文件映射时,手游被改动地页面才写回磁盘。

通过共享内存来通信:
(1)共享内存是通过映射相同文件到通信进程地虚拟地址空间实现的;
(2)当多个进程映射到同一个文件的时候,各进程地虚拟地址空间都是相互独立的,但操作系统将对应地这些虚拟地址空间映射到相同地物理内存(用页表实现)。

内存映射文件的好处:
(1)使程序员的编程更加简单,已建立了映射的文件,只需要按照访问内存的方式进行读写;
(2)方便多个进程共享同一个磁盘文件。

虚拟存储器性能影响

1、缺页率是影响存储器性能的主要因素,而缺页率又受到页面大小、分配给进程的物理块数、页面置换算法以及程序编制方法的影响。

2、页面大小
(1)页面较大:缺页率低、页表项长度短,但是页内碎片大
(2)页面较小:减少了页内碎片,有利于提高内存利用率,但是缺页率高,页表项长度长,占用大量内存空间。

3、分配给进程的物理块数目越多,缺页率就越低,但其超过一定阈值时,物理块的增多对缺页率的改善并不明显。就像元素精通的收益曲线:对数函数。

4、好的页面置换算法会保持一个较低的缺页率。选择LRU、CLOCK置换算法,将未来有可能访问的页面尽可能地保持在内存中,从而提高页面访问速度。

5、编写程序地局部化程度越高,执行时地缺页率越低。若采取地是按行存储,则访问时就要尽量采用相同的方式,避免按列访问造成缺页率过高地情况。

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

♡すぎ♡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值