操作系统—— 3 虚拟内存

1. 虚拟内存的起因(缓解内存不足)

内存越来越不够用,程序规模的增长速度远大于存储器容量的增长速度
在这里插入图片描述
registers(寄存器):把更小更快的存储器放在离CPU近的地方,使CPU更快访问到
Cache:由于内存相对寄存器速度较慢,所以在中间加一个cache,缓存内存数据,使得CPU取数据尽量从cache取,而不需要每次都访问主存,保证速度快
把寄存器和Cache容量做大不太切实际
内存现在越来越大,然而软件越来越大
硬盘速度太慢,不能把程序放在这执行,考虑将硬盘容量用上。希望操作系统能帮助程序员利用这些硬盘空间,分页分段之上解决容量不够的问题
在这里插入图片描述
在这里插入图片描述
最开始,内存很小,需要程序员手动写代码,把一些常用的数据保存到内存
后来,由os把不用的数据导出到硬盘,开销大
把程序中的一部分数据导出,基于分段分页+os管理实现虚存

2. 覆盖技术(80年代90年代初)

dos系统 小内存却要运行大程序
在这里插入图片描述
原理:将程序根据执行逻辑进行分类,划分为若干个区间(相对独立的模块)。不能同时运行的模块设置其为共享空间,按时间模式依次执行(分时),要设置常驻内存空间,负责管理何时将相应的函数数据调入调出,不常用的数据要放到外存
在这里插入图片描述
A调用B、调用C
A先调用B,所以B从硬盘调入内存,此时,A又调用C,则把B使用的空间释放掉,把C从硬盘调入内存;C调用E,则把E从硬盘调入内存。。。
粒度以程序的逻辑调用关系来实现
逻辑调用关系不止一种覆盖方法:
在这里插入图片描述
缺点(开销):

  1. 程序员设计的开销(如何找到最佳的覆盖方法使得占用空间最小)
  2. 数据的换入换出(时间换空间)
    在这里插入图片描述

3. 交换技术

操作系统帮助完成
在这里插入图片描述
不用的程序且内存不够就把它换出去,用的时候再换回来
粒度:一个程序
问题:

  • 什么时候交换?内存不够时才作此操作
  • 交换区大小?要够那个程序运行
  • 程序换出后再换入位置不一样了?若换入后还是以前的位置,继续执行;若不是原来的位置了,就采用动态地址映射(页表,动态表变化的,虚地址与实地址的映射关系是动态变化的)
    在这里插入图片描述

覆盖与交换

覆盖发生在一个程序里,交换是在程序间
覆盖由程序员手动指定逻辑关系,粒度是模块;交换由操作系统内部完成,粒度是程序,开销比较大

4. 虚拟内存管理技术(虚存技术)

在这里插入图片描述
为解决覆盖和交换存在的问题,提出了虚存技术
目标:

  • 和覆盖一样,内存中存的不是整个程序,但此操作由os来完成
  • 和交换一样,对其进行换入换入换出,但粒度小
    在这里插入图片描述
    对于P3,不是所有的数据都放在了内存

程序的局部性原理

指程序在执行时呈现出局部性原理,即在一段时间内,整个程序的执行仅限于程序中的某一部分。相应的,执行所访问的存储空间也局限于某个内存区域。
局部性原理又表现为:时间局部性和空间局部性。

  • 时间局部原理是指如果程序中的某条指令一旦被执行,则不久后该指令可能再次被执行;如果某数据被访问,则不久后该数据可能再次被访问。
  • 空间局部性是指一旦程序访问了某个存储单元,则不久后,其附近的存储单元也将被访问。
    (更详细的见https://www.jianshu.com/p/5c9b28c95c64)
    如果能实现程序的局部性原理,就可以高效的完成虚存技术
    在这里插入图片描述
    在这里插入图片描述
    按行存储
    在这里插入图片描述
    一页为4K,而a0,0到a0,1023占210 *4=4K(这应该说的是int在32位机器上占4个字节吧)
    一页正好是数组的一行
    解法1将先将a0,0-a0,1023调入,访问完a0,0后,访问a1,0,需要再次调入a1,0-a1,1023,产生缺页,开销很大

基本概念

在这里插入图片描述
把程序的一小部分放入内存中,如果要访问的指令或数据不在内存中,就把它从硬盘中调入,如果内存足够大,直接调入,如果内存不够大,则由os来选择一个以后不会或较少用到的部分调出内存

基本特征

  • 空间大:物理内存和硬盘相加得虚拟空间
  • 部分交换:换出的是段或页,不是换整个程序
  • 不连续:物理内存分配得不连续,虚拟地址空间使用的不连续(本来所有的都应该放在内存,但是某些数据或代码会被换出去,所以会不连续)

虚拟页式内存管理

在这里插入图片描述

  • 大部分采用页式存储管理,还要增加请求调页和页面置换功能
  • 基本思路
    • 请求调页:只装入部分页,访问到不在内存的页时,请求调页,CPU向操作系统发出缺页异常,根据缺页的信息找出相应的页,调到物理内存中去
    • 页面置换:内存不够时调入调出
      在这里插入图片描述
      为实现调换和置换,增加几个位
  • 驻留位:该页在内存还是外存
  • 保护位:能否访问该页
  • 修改位:该页是否被写过。如果被写过,说明与放在硬盘得数据是不一致的,在做换入换出时,要写回;若没被写过,则直接释放该页
  • 访问位:当前页是否被经常访问,若不是经常访问(0),则可以换出
    在这里插入图片描述
    在这里插入图片描述
    左面是页表
    MOV REG,0 //8192
    把虚拟的0地址赋给寄存器,页表里0对应的是2,2一个页的大小即24K=2*4096=8192,所以物理地址位8192

MOV REG ,32780 //缺页中断
即页表项第8项 32K-36K(32780/1024=32.011),该项是X,所以是缺页
在这里插入图片描述

  1. 若CPU执行一个指令,若内存地址无对应的映射关系,则缺页异常,os来处理,看内存中是否有空闲空间,若有,则分配一个物理页帧,转到第4步,把该物理内存以页的单位转入到分配的物理页帧那,然后修改页表,把存在位置为1,重新执行指令
  2. 空闲空间没有了,则要采取页置换算法
    在这里插入图片描述
  • 数据文件,如一个数组形成的在硬盘上的,访问若没有,则从硬盘中把这个数据文件读出来
  • 代码,每一条指令也是数据,放在硬盘,把执行代码作为数据,读入内存,进一步执行
  • 库文件:需要才从硬件读出来
  • 程序在运行过程中会产生数据,这些数据占空间且需要换出到硬盘,硬盘直接开辟一个空间(swap file)
    以上保证了空间有效性
    在这里插入图片描述
    p——缺页概率
    q——对也需要写回的概率
    EAT=10(1-p)+5,000,000p(1+p)
    (1+p):写回还要占的时间
    p足够小,则是EAT接近10,若程序具有局部性原理,则效率很高,则会接近10

5. 页面置换算法

5.1 功能和目标

功能:当缺页中断发生时,需调入新的页面而内存已满时,选择内存当中哪个物理页面被置换
目标:尽可能地减少页面换进换出次数(即缺页中断的次数),因为硬盘读写速度慢,所以要尽量减少次数
在这里插入图片描述
常驻内存要进行页面锁定
在这里插入图片描述
在这里插入图片描述
因为找的时候如果那一个也都不存在了,也就不需要再看偏移量了,所以就只需要考虑页即可
不太可能做到不缺也,只能缺页概率减少

5.2 最优页面置换算法

根据将来这个程序会访问哪个页来设计
很难实现
但可以把算法算作最佳的评算标准,越逼近则越好
在这里插入图片描述
在这里插入图片描述

5.3 先进先出算法(FIFO)

在这里插入图片描述
驻留最久的就被换出
使用一个链表,链表头部是驻留时间最久的页面,尾部插入的是驻留时间最短的
在这里插入图片描述
实现简单,但产生的缺页次数较多

5.4 最近最久未使用算法(Least Recently Used,LRU)

在这里插入图片描述
选择过去最久未使用的页面,来推测未来,最优是根据未来推测未来
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.5 时钟页面置换算法

Clock 页面置换算法,LRU的近似,对FIFO的一种改进
访问位,若访问则置1,由硬件完成
在这里插入图片描述
把各个页面组织成环形链表(放在物理内存),若访问位为1,则是个老页,指针下移,若访问位为0,则不是老页,就可以把它换了
是否是老页,依据是访问位
在这里插入图片描述
依据(右边数第2位)
当前指向page 0: 1 1 4,访问位为1,说明最近被访问过,此时需把访问位置0,再把指针顺时针下移,接着找访问位为0的,找到Page3,再找到Page1,所以把Page1 的页表项换掉
在这里插入图片描述
与LRU缺页次数差不多
注意:当访问位为1时,将访问位置为1并下移指针
访问:读和写都是访问

5.6 二次机会法

在这里插入图片描述
脏位:写操作则置为1,由硬件设置
若进行读操作,则内存和硬盘的数据一致,无需写回
若进行写操作,则内存和硬盘的数据不一致,需写回
提出二次机会法(Enhanced Clock algorithm),同时利用脏位和访问位来决定那页可以置换,以减少写回
上图右下角为替换规则,如2位均为0,则该页可以替换,如分别为0,1,则把脏位设为0,指针下移
如2位均为1,则变为0,1,指针下移,当指针再次回到该页时,变为0,0(这里体现了2次机会)经常使用的dirty位会更少的换出
在这里插入图片描述
带上标的为对其进行写操作
第5次过程:

  • a:1,1->a:0,1

  • b:1,1->b:0,1

  • c:1,0->c:0,0

  • d:1,0->d:0,0

  • a:0,1->a:0,0

  • b:0,1->b:0,0

  • c:0,0->e:1,0

5.7 最不常用法(Least Frequently Used,LRU)

访问次数最少,则换出
在这里插入图片描述
简单的使用计数器的弊端:

  1. 如果把计数器用一个寄存器来存,则硬件开销很大
  2. 如果对计数器进行查找,要查找链表,访问也很大,链表很长,就会早场访问时间过长

LRU和LFU的区别:

  • LRU考察的是多久未访问,时间越短越好
  • LFU考察的是访问的次数或频度,访问次数越多越好(问题:一个页面在进程开始时使用得较多,但以后就不使用了,实现也很费力,解决方法:定期将次数寄存器右移一位,即次数除以2)
    在这里插入图片描述
    (这个???)

5.8 Belady现象、LRU、FIFO、Clock的比较

Belady现象:在采用FIFO算法时,有时会出现分配的物理页面数增加,缺页率反而提高的异常现象
在这里插入图片描述

  • 分配物理页数为3
    在这里插入图片描述
    只有3次访问命中
  • 分配物理页数为4
    在这里插入图片描述
    只有2次命中
  • LRU不会产生这个问题(符合栈算法,未展开讲)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    如果程序本身没有局部性特征,则LRU可能会退化为FIFO(LRU和FIFO和Clock会变得差不多)
    Clock算法使用一个访问位
    在这里插入图片描述

6 全局页面置换算法

6.1 局部页替换算法的问题、工作集模型

在这里插入图片描述
由上图可知,当分配3个物理页帧时,9个缺页,当分配4个物理页帧时,1个缺页数,物理页帧数目会对缺页数有影响
当对一个程序分配的物理页帧数目相同时,限制了程序产生缺页的特点,因为程序在运行过程中有阶段性,可能一开始需要很多内存,中间很少,最后又很多,是动态变化的。假定os只能跑一个程序,分配给它所有的物理页帧,但是不是只跑1个程序,如果给每个程序分配的物理页帧数固定,则这样是不灵活的

工作集模型

在这里插入图片描述

1 工作集(working-set)

工作集:一个进程当前正在使用逻辑页面集合
当前正在使用:是一个时间段,起始时间和它的一个持续长度,代表当前
逻辑页面集合:存了该程序这段时间内访问的页面
在这里插入图片描述
t:当前执行时刻
deite:一个长度,一个定长的页面访问的时间窗口
t+deite=1个时间段
t会变,而deita不会变,w会变
在这里插入图片描述
t2那个局部性较好
t1那个有的部分局部性较好,有一定的局部性,而整体局部性不如t2
在这里插入图片描述

2 常驻集

常驻集:指当前时刻,进程实际驻留在内存当中的页面集合
在这里插入图片描述
不是分配给程序越多的物理页帧越好,当此程序运行时,有多余的物理页帧可以动态分配给其他程序,会降低缺页率。
给不同的程序分配不同的常驻集,缺页次数变少,性能提升,这样操作,局部页面算法是无法解决的

6.2 两个全局置换算法

6.2.1 工作集页置换算法

替换不在工作集里的页
随时间推移,不属于工作集的也会被扔掉
在这里插入图片描述

时刻 工作集
0 {a,d,e}
1 {a,c,d,e} 中断
2 {a,c,d} t=-2:e,t=-1:d,t=0:a,t=1:c,t=2:c而窗口大小为4,所以e就不在工作集里了
3 {a,c,d}
4 {b,cd} t:0:超出工作集窗口
{}

超出工作集窗口的页面都会被换出去,所以可以给其他程序空间,使整个系统缺页次数降低

6.2.2 缺页率页面置换算法

使常驻集大小可变,一种更灵活的全局算法
依据是缺页的频度,缺页次数多,则分配更多的物理页;缺页次数少,则分配的物理页够多,则可以压缩常驻集
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当前产生中断的时刻-上一次产生中断的时刻
在这里插入图片描述
工作集的是得每一次都要判断是否超出工作集
而缺页的是只有在中断时才考虑
这2个都是动态调整,而局部的是只有满的时候才调整

6.2.3 抖动问题

在这里插入图片描述
工作集代表着本身对内存访问的固有属性
常驻集是os当前把程序运行需要的页面放到内存

在这里插入图片描述

  • 平均缺页时间(MTBF)= 页缺失服务时间(PFST)
  • 内存大小
    红线:随着程序运行的越来越多,CPU越来越多,都用来换入换出了
    内存用完了,就会产生缺页,要进行大量的换入换出,使得os把大量时间用在中断
    os希望达到程序运行的多并且系统利用率高
    需要平均缺页时间与页缺失服务时间尽量相等,比值越大说明缺页频度越低,找到NI/O-balance 跑的程序很多,缺页数较少
发布了16 篇原创文章 · 获赞 0 · 访问量 242

猜你喜欢

转载自blog.csdn.net/qq_42713936/article/details/105019966