操作系统(8)虚拟内存

1. 硬件和控制结构介绍

虚拟内存:允许进程执行时只将部分程序放入内存,因此程序可以比物理内存大

术语:①虚拟内存:用辅助存储器(一般指磁盘)作为内存的补充。虚拟内存的大小受计算机寻址和可用的辅助存储器容量限制,而不受内存容量的限制。看上去,进程的可用内存大小比实际内存大小要大得多,但这个“内存大小”不是真实存在的,是通过OS和硬件MMU模拟出来的

②虚拟地址:即逻辑地址。虚拟内存中某字节的地址,仿佛该字节存在内存中,其实可能位于磁盘,但这对用户透明

③虚拟地址空间:分配给某进程(程序)的虚拟地址范围

④实地址:即物理地址。物理内存中某字节的地址。

⑤驻留集:进程运行时装入内存的部分

当访问一个不在内存的逻辑地址时,产生缺页中断/缺段中断;OS将阻塞该进程,启动磁盘I/O,装入所需的页/段后,将阻塞进程置为就绪态

虚拟内存可提高系统资源利用率,方便用户编程:

每个进程只需装入(最近一段时间内访问的)部分页/段,所以内存中可放置更多进程,系统并发度更高,于是提高了CPU利用率(多道程序度)更高,于是提高了CPU利用率和内存利用率

进程可以比内存容量还大。程序员看到的是一个与磁盘容量有关的巨大内存,而虚拟内存由OS和硬件实现,如何实现则对程序员透明

虚拟内存的硬件支持:内存管理单元MMU(集成在CPU中,或作为一个协处理器)。

MMU功能:分解逻辑地址;逻辑地址到物理地址的转换;查找/更新块表TLB;进程切换时清空TLB;发出缺页中断或者越界中断;设置和检查页表中的各个特征位等。

2.局部性和虚拟内存

程序执行具有局部性原理,包括时间局部性和空间局部性,表明:进程对代码和数据的引用和访问有集簇倾向,所以虚拟内存方案可行。

虚拟内存的特征:

运行进程时只把最近一段时间内要访问的页/段装入内存,其余页/段放在外存,需要时再利用请求调入页/段功能和置换功能将其调入内存

从逻辑上扩充容量;访问速度接近于内存,每位(bit)成本接近于外存 

就绪挂起态和阻塞挂起态进程的换入 / 换出内存 和虚拟内存的换入 / 换出内存有什么区别?
就绪挂起态 / 阻塞挂起态 进程的 所有 内存驻留页 / 段全部 被换出,解除挂起时,所有以前的驻留页 / 段再重新读 回内存。且 CPU 不会调度就绪挂起态进程。
虚拟内存: 运行态 进程运行时发生缺页 / 缺段,此时将 它的 部分 / 段换入和换出内存。

3.分页 

3.1 页表结构

虚拟内存中的页表结构:

 缺页中断(页错误):①在一条指令执行期间,当要访问的页不在内存中时,产生和处理缺页中断,然后重新执行该指令

②一条指令的执行可能导致多次缺页中断

3.2 虚实地址转换 

虚拟地址<页号,页内偏移> ->实地址<页框号,页内偏移>

首先分解虚拟地址,从虚拟地址读取页号,得到页号后请求页表寄存器页表数据,从页表中查找页号所对应的页框号,再把虚拟地址的偏移位和页框号进行拼接,即为实地址。

3.3 两级页表

两极页表:32-bit机器上,每个进程地址空间为(2^32)B,页长4KB,则页表最长将到达(2^20)1M个项。若每个页表项占4B,则存放这张表将需要连续的4MB连续内存。而且每个进程的页表都可能这么大。

于是我们可以将这张长页表划分为多个“页表页”(也就是将这张长页表拆开,然后再搞一张页表,这个页表存的是这张长页表被拆开之后各个片段的编号(地址)),这样可以使得页表页也离散地、尽量地占用内存,甚至仅部分装入内存

因此32bit的地址也被划分为

3.4 两级页表例子

 首先先把长页表拆开,拆开之后就产生一个根页表,该根页表上的值是值得是该页表页的存放地址,然后去根据该值拿出该页表页。

对于地址转换而言,p1能够拿去查询根页表,根页表中的值再拿去查询内存中的块号(帧号),查到了之后就得到了真正存储想要数值的页表,然后根据页内偏移定位数值。

对于更大的内存,更大要求的虚拟内存空间而言,可以再采用更高级的页表存储方案,也就是页表的页表的页表的页表.....

1 、多级页表的优点是 ___D__
A. 加快地址变换速度 B. 减少缺页中断次数 C. 减少页表项所占字节数 D. 减少页表所占的连续内存空间 

2、假设采用页式存储,48位逻辑地址,页面尺寸4KB,页表项大小为8B,则应采用页内偏移____12__位,____4__ 级页表。

A. 12, 3 B. 14, 3 C. 12, 4 D. 14, 4
解析:首先页内偏移与页尺寸有关,4KB=2^(2*10)=2^12,因此需要页内偏移12位,然后剩余的36位作为页号位,
那么页号位应当如何确定呢?
首先我们可以计算出,一个页内可以放多少页表项:2^12/2^3=2^9,那么一级页表的表示就需要9个bit
剩余36位,那么可以用36/9=4级页表

4.分页策略 

4.1 倒排页表

倒排页表为内存的每一页框设置一个页表项

页表项内的内容是该帧所属进程的标识和页号<pid,page#>

这种策略的存在是因为当操作系统是64位时,地址的表示也就变成了64位,如果用原本的分页策略(也就是每一个页框存储的是每个进程所对应的页号)的话,此时页表就会相当庞大,因为用来表示地址的位数变多了,但是用倒排页表的策略的话,地址的高位就变成了内存的下标,内存的大小通常是4GB,8GB,16GB等等,这样的页表大小就会被大大缩小。

这个策略相对于之前的寻址方式最大的区别在于,之前是通过逻辑地址去找页号再找物理地址,现这个策略的逻辑是物理地址是下标,逻辑地址是内容.

在寻址过程中,可以看做是顺序遍历内存数组,用进程号和页号去同时匹配内存框内的页表项内容,匹配到了,就把下标拼到物理地址上。

由于是顺序遍历,平均遍历时间复杂度是O(n),对于内存这样的大容量数据单元来说,是难以忍受的,因此应当采用哈希表这个数据结构来优化该算法。

对虚拟地址<pid,page#>用散列函数映射到散列表中,具有相同的哈希值的表项被链在一起,可以减少时间。散列函数的作用是将长队列分成若干短队列

4.2 引入快表 

上述页式管理机制带有的问题有:每次访问数据都需要访问两次内存,一次访问页表以得到地址,一次根据地址访问数据

解决方案是引入快表(转换检测缓冲区TLB),也称为快表

将页表中进程运行最常用的部分放入TLB,TLB集成在CPU内部的MMU里面。(TLB不同于Cache)

地址转换时:若要访问的页号位于TLB中,则从TLB中取出帧号。否则从内存中的页表取出页号,并将该表项加入到TLB中。当TLB满后,淘汰旧表项,再写入新表项

首先我们需要纠正TLB是小内存的这一种观念,TLB实际上是有硬件支持的,因此本质上就与内存不同。

寻址过程:首先虚拟地址被拆分,得到高位的页号,高位的页号通过并行匹配查找,在TLB中查找对应的帧号,

若TLB命中,则帧号被拼到页内偏移之前成为新地址,然后根据该物理地址去访问内存

若TLB不命中,而在内存中的页表命中,此时在内存中查找页号,通过该页号去查找帧号,然后根据该帧号读取数据

若内存中的页表也不命中,此时发生缺页中断,从硬盘中调度对应的页到内存中,将所缺页装入内存,更新页表和TLB。

4.3 缺页中断和TLB-例子

完整的算法流程如:

 例:不考虑缺页中断且忽略TLB并行匹配查找时间,设访问内存的时间为100ns,访问快表TLB的时间为20ns。如果TLB命中率为90%,则将逻辑地址转换成物理地址并访问内存数据所需的有效访问时间是

解析:这道题是对上述过程的一个回顾,若访问TLB就直接得到命中了,那么访问时间是20+100(获取数据)

否则就是访问TLB不直接命中,此时就要访问内存中的页表(20+100+100)

注:第一个20是访问TLB的(包含更新TLB),第一个100是访问内存页表的获取帧号的,第2个100是根据帧号和偏移获取内存数据的

因此答案为:(20+100)×90%+(100+20+100)×10%=130ns

不用 TLB 时,需访问两次内存, 100 × 2=200ns

5.页尺寸 

页尺寸考虑因素: 512B-> 1KB-> 4KB-> 8KB->
页内碎片:页越小,碎片越小。
页表长度:页越大,页表越短。
磁盘开销:页越大,磁盘 I/O 开销越小。
内存容量和程序大小:内存越大,页也可以越大
程序局部性:页越小,局部性越好,且可装入更多的页,缺页率低。
页增大时,局部性被削弱, 缺页率逐渐升高。但继续 增大页,缺页率反而降低

很多CPU支持多种页尺寸,但大多数OS只支持一种页尺寸。

6.分段原理

以段为单位分配内存及内外存交换。段不等长。
当发生缺段中断时,可能需要移动或 淘汰多个段才能满足新段的需要。
每个进程一张段表。段表结构:

驻留位:该段是否在内存。
修改位:该段装入内存后是否修改过。
访问字段:指示最近被访问次数或距上次访问的时间间隔。
存取权限:本段的存取权限是可写、只读或执行。
扩充位:指示此段是否可动态增长。越界时如果该段不可扩 充则出错,否则增加段长并分配下方空闲内存。

7. 段页式-基本原理 

核心理念:将用户程序划分为段,段再划分成大小相等的页

内存划分为和页同样大小的帧(页框),以帧为单位离散分配内存。每段最后一页有内碎片而无外碎片。

要确定段内地址,逻辑地址需要由段号,段内页号,页内地址来唯一确定 

首先就是有一张段表,存储该程序段分割出来的所有段,然后该段表的表项代表着分割出来的段号的序号,然后存储该段的所对应页的长度以及起始地址,根据该起始地址和长度定位页表,再根据页表查找段再内存中的位置。

8.段页式-地址转换

8.保护和共享

简单分段和虚存分段易于保护和共享。

存取权限:各段有执行、读、写等权限

地址转换通过各自的段表来执行,防止越界

共享段在多个进程段表中的起址和长度相同

也可用“CPU四级特权环”实现保护

在这些存储管理方法中: 简单页式,简单段式,虚存 页式,虚存段式,虚存段页式,动态分区,固定分区
固定分区:支持多道程序设计,算法简单,但内碎片多
动态分区:无内碎片,但用于外碎片的压缩处理时间较长
简单页式:克服了碎片多和压缩处理时间长的缺点,但不支持虚拟内存
虚存页式:支持虚拟存储,离散分配内存,无外碎片,但不能以自然的方式提供内存的共享和存取保护机制
虚拟段式:易于共享和保护,内存碎片多,支持虚拟内存
虚拟段页式:易于共享和保护,内存碎片少,支持虚拟内存

9.虚拟内存的软件实现 

CPU必须支持分页和分段,才能实现虚拟内存

现代OS均实现了页式或者段页式虚拟内存

虚拟存储管理需要考虑的问题:

-读取策略:某一页何时调入内存(请求调入/预调入)

-置换策略:选择哪一页换出内存(FIFO/LRU等)

-驻留集管理:给进程分配多少帧(固定/可变帧数),置换时牺牲谁的帧(全局置换/局部置换)

-清除策略:何时将脏页写回磁盘(请求清除/预清除)

-加载控制:调整系统并发度,防止抖动

9.1 虚拟内存的读取策略

何时把页面装入内存,有两种策略:

请求调入:仅把需要访问的页调入内存

预调入:考虑到启动磁盘的寻道和延迟开销,在调入所需页的同时,也调入若干可能马上访问的页面(通常是所需页的后面几页)

9.2 虚拟内存的放置策略

进程的页/段放在内存的哪个位置:

页:离散地放在内存任意帧

段:首次/下次/最佳适配等算法策略分配

非一致存储访问多处理器:即分布式集群系统或集群,多个节点(计算机)各有本地内存。数据驻留的节点应与使用数据的节点尽量近,使得数据访问尽量快

10.虚拟内存的置换策略

置换策略是用来应对当内存中的所有帧已被分配,又必须装入一个新页时,选择在内存的哪一页被置换出内存。

策略目标:基于局部性原理,根据进程过去的访问行为预测将来的访问行为,置换那些(将来)最近一段时间内最不可能访问的页

算法:最佳置换(OPT),最近最少使用(LRU),先进先出(FIFO),时钟(CLOCK)

页框锁定:有些帧可被锁定在内存、不能被置换。如操作系统内核、系统数据结构、I/O缓冲区(正在I/O的页)等

10.1 置换策略-OPT算法(最佳置换)

OPT:淘汰那些永不再使用或者下次访问距当前时间最长的页面

最佳,但不可实现,用于衡量其它置换算法性能

 

用OPT的算法思想对本题进行求解,首先请求2号页,产生缺页中断,调入该页到内存中,再请求3号页,产生缺页中断,调入该页到内存中,后面再请求2号页,此时不再缺页,直接读取数据,再请求1号页,产生缺页中断,调入1号页到内存中,请求5号页,此时内存帧中没有,就启动置换算法,开始置换内存中的页,在OPT算法下,是假设可以直接获取将来将要请求的页的,因此从请求5号页的那个时刻开始看,2号页在下一次访问时将用到,3号页将在后面的第四次访问到,而1号页再也没有访问到,那么最优选择就是置换掉1号页,调入5号页。大致流程就是如此。

该算法是最优的算法,但是是不可实现的,通常作为标尺来衡量算法的优劣

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

LRU:最近最久未使用算法,淘汰在最近一段时间内最近未使用的一页。

实现:可为每页添加“上次访问时间戳”。开销大

假设:以过去预测将来,最近使用过的页可能很快被再次使用,很久未用的页可能不会被立即使用

首先装入新内存的就不再赘述了,直接看置换新内存的,当需要调入5号页时,此时开始回溯以前调入的页,1号页刚被访问过,2号页在上两次被访问过,3号页是距离被访问时间最长的,因此3号页要被置换掉。

10.3 置换算法-FIFO算法(先入先出算法)

FIFO:淘汰驻留内存时间最久的一页。

实现:将页面按调入内存的时间先后排成一个队列,每次将淘汰队首页,性能差

Belady异常现象:通常,帧越多则缺页次数越少,但FIFO算法中,有时,帧越多反而缺页率越高

10.4 置换算法-简单时钟算法 

每个页表项设一使用位:页号-帧号-使用位U

某进程的所有页面(或整个内存的页框)排成一循环缓冲链;某页被装入或访问时,其使用位U置1

置换时顺序查找循环链,U=0,置换该页,U=1,将U置0,替换指针前移,下次置换时从替换处开始寻找。

 简述上述流程:首先开始发生了置换,置换指针一开始指向下标为2的页框,然后发现其位U为1,替换指针向下滑动,将其位U置为0,替换指针再向下滑动,发现其位U为1,替换指针向下滑动,将其位置为0,然后继续向下滑到4,到4的时候就发现了一个位U为0的,符合置换要求,将其置换,换入新页,将新页的位U设置为1.

首先这道题可能有点难懂,看第一次2号页被置换的过程,可能有些跳步,在装入1号页后,所有的页都是被访问过的,都带了颗*,然后开始置换,指针一直向下滑,将所有页都刷成了0,此时指针又指向了2,所以2被替换掉了,记住替换完了之后,替换指针还要下滑一位。

10.5 替换策略-时钟算法改进

 每个页表项设置“使用位U+修改位M”,访问某页时U置1,被修改时M置1,则有四类页面

①U=0,M=0(最佳淘汰页)②U=0,M=1,③U=1,M=0④U=1,M=1

问题在于,②和③的淘汰先后顺序应该如何确认?

 查找最近未被访问但被修改的页,即使置换这样的页必须先写回,但是根据局部性原理,它不会很快又用到,因而节省了时间

 考虑一个进程的页访问序列,工作集为M个页框,最初都是空的。页访问串的长度为P,包含N个不同的页号。对任何一种页面置换算法:

a. 缺页中断次数的下限 ( 最少次数 ) 是多少?
b. 缺页中断次数的上限 ( 最多次数 ) 是多少?

下限就是初始化空内存到将所有需要的页帧都加载进内存中的次数,也就是页的数目,N个

上限就是每次访问页的时候都缺页,P次

10.6 页缓冲技术

页缓冲技术采用FIFO,系统总是保留一个空闲帧的链表,缺页时选择一个牺牲帧,但无需等待牺牲帧写出,所缺页就可以装入到链首的空闲帧中(以尽快运行程序)。对于所选中的牺牲页:

①若它未被修改(干净页),则将其页表项放到空闲帧链尾

②若它已经被修改(脏页),则将其表项写入修改页链尾,当磁盘空闲或修改页链达到一定长度的时候,集中成批地(簇方式)地写回磁盘,再移到空闲帧链中,(而且保留原"PID+页号+帧号"的结构)

③当发生缺页时,先检查所需页是否在空闲帧链/修改帧链中,若在,则从链中直接取出,不需要磁盘I/O,若不在,则用一个新的空闲帧来装入所需页

④优点:当FIFO置换算法错误地置换了一个常用页时,该页被放在空闲帧链或者修改页链(的尾部),可以在内存中保留一段时间(帧内容不清空),如果马上又用到该页,可以很快将该页从内存中回收,而无需从磁盘读出。

11.驻留集管理

11.1 缺页率的影响因素

缺页率=不成功访问次数/总访问次数 

在为进程分配主存时,每个进程的帧越少,内存中的进程就越多,并发度越高,如果进程只有小部分在内存里,缺页率将会相当高,此时为进程增加一些内存帧,将会显著降低缺页率,但分给进程的内存帧超过一定限度之后,继续增加帧,也不会明显降低进程的缺页率。

但是主存的容量是有限,如果没有限度地为某一进程分配主存,那么其他进程分配的就少了,其他进程的缺页率就会升高,则这时候反而效果不好,所以我们需要找到一个可接受的缺页率: ①如果缺页率太高,将增加进程帧数②如果缺页率太高,将减少进程帧数

缺页率对内存有效访问时间的影响:

设内存访问时间为 m=100ns ,缺页率为 p ,缺页中 断处理时间为 25ms ,则:
有效访问时间 = (1 p) × m p × ( 缺页中断处理时间+ m)
= (1 p) × 100ns p × (25000000 100)ns
= (100 25000000 × p)ns
还要加上一个100的原因是处理中断后,还要再次访问内存
若要求有效访问时间小于 110ns ,即仅延长 10% p<0.0000004 ,即约 2500000 次访问时,才发 1 次缺页。
每页装入内存后可能访问成千上万次 ( 字节级 ) 

11.2 工作集

工作集wi(t,δ),在t时刻,进程pi在过去的δ个时间单位内访问的页面集合(活跃页面)

当一个进程的工作集都在内存时,可使缺页率达到“可接受的下限”

若缺页率继续降低,将减少进程驻留集的大小

11.3 页面分配数量

固定分配 :进程分得的页框数固定不变。
平均分配:如 100 个帧, 5 个进程,每进程 20 帧。
比例分配:按照进程大小来分配帧。 s i = 进程 p i 大小; S = ∑s i m = 帧总数;
a i = 分给进程 p i 的帧数 = (s i /S) * m
如所有进程共需 200 页,某进程需 10 页占 5% 内存 100 帧,则该进程分得 5
- 按优先级分配:使用比例分配策略,但不是根据 进程大小,而是根据进程优先级。
可变分配 :根据缺页率,进程分得的页框数可动 态增加或减少。

11.4 置换范围

局部置换:每个进程只从它自己的已分配帧中选择置换帧

全局置换:进程在整个内存范围内选择置换帧

11.5 驻留集管理

固定分配+全局置换 冲突,无此方案。
固定分配+局部置换 不灵活
可变分配+全局置换 剥夺哪个进程的帧合适呢?
可变分配+局部置换 经常配合使用:
新进程装入主存时,根据应用类型、程序要求, 分配给 定数量页框
缺页中断时,从该进程驻留集中选 页置换
不时重新评价进程的分配,增加或减少分配给进 程的页框以改善系统性能。

11.6 清除策略

何时把 个修改过的页面写回磁盘,两种策略:
请求式清除 :仅当需置换这个脏页时把它写回, 之后再调入新页。 但每次清除都需 2 次磁盘 I/O :写旧页,读新页。
预清除 :即使还不需要置换脏页,也成批地把 它们写回 ( 例如当磁盘空闲或脏页达到 定数量 ) ,可降低磁盘 I/O 开销。 但这些页被置换前仍留在内存,可能再次被修改
可采用页缓冲算法清除 个脏页

12.抖动

当系统并发度 ( 多道程序度 ) 过高时,缺页频繁,用 于调页的时间比进程实际运行的时间还多, CPU 利用率急剧下降,此时发生了 抖动 ( 颠簸 )
原因:所有进程工作集的帧需求总量 > 内存帧数
解决:抖动时,挂起 些进程,释放它们的帧

采取哪些措施可以预防抖动

在调度程序中引入工作集算法:当各进程的内存驻 留集足够大时,才调入新作业。
L=S 准则:调整并发度,使得 产生缺页的平均时间 ( 即缺页中断之间的平均时间 ) 等于处理 次缺页中 断的平均时间 ,此时 CPU 利用率最高。

 50%准则:磁盘利用率50%时,CPU利用率最高。

采用局部置换:只在本进程的内存范围内置换。
当系统并发度较高时,挂起若干进程 (如优先级最 低的、最年轻的、发生缺页的、占空间最少的、占空间 最多的、剩余运行时间最长的进程

 个分页虚拟存储系统,测得CPU和磁盘利用率如下。问每种情况下存在的问题和可采取的措施

1. CPU 3% ,磁盘 97%
系统可能已经出现抖动,可暂停部分运行进程
2.CPU 87% ,磁盘 3%
此时系统运行正常,但磁盘利用率较低,可增加进程 数以提高资源利用率;
3.CPU 13% ,磁盘 3%
CPU 和磁盘利用率都很低,可增加并发进程数。
4.CPU 93% ,磁盘 49%
此时系统即将发生抖动,不可再增加进程。
  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值