页替换策略
当我们需要分配物理页时,若空闲的物理页已经用完或者小于一个阈值。
那么此时操作系统会选择 页替换策略 选择一个或者一些物理页换出到磁盘以便
让出空间。当已经被换出的内存页再次被访问时,必须重新从磁盘加载到物理
内存,十分耗时!!!- 页替换策略是根据硬件所提供的页访问信息,来猜测页应该被换出 ( 比如短时间内再次被换入的小概率的页 ),从而最小化缺页异常的发生次数以提升性能。与此同时,操作系统也需要考量 页替换策略本身执行所带来的开销。不同的页替换策略 有其各自适合的应用场景。
MIN 策略 / OPT 策略
- MIN 策略又称 OPT 策略。
- 这一策略在选择被换出的页时,优先选择未来不会再访问的页,或者在很长时间内不会再访问的页。
这一策略理论上来说,是最优秀的页替换策略,但在实际场景中通常很难实现。
页访问顺序取决于应用程序,而操作系统通常无法预先得知应用程序未来访问页的顺序。
该策略主要作为一个标准,来衡量其他页替换策略的优劣。- 我们来模拟一下,假设物理内存中可以存放三个物理页,初始为空,一个应用程序需要访问物理页 1 – 5,顺序为 "3 2 3 1 4 3 5 4 2 3 4 3 ";
FIFO 策略
- FIFO 策略是最简单的页替换策略之一,同时也正因为简单所以带来的时间开销很小。
- 该策略优先选择最先换入的页进行换出。
- 操作系统维护一个队列用于记录换入内存的物理页号。每换入一个物理页就会把它的页号加入到队尾,因此最先换入的物理页号总是处于对头位置。
- 当需要选择一个物理页换出时,该策略总是选择位于队列头部的物理页号所对应的物理页。
但其实这种策略所带来的性能很低,因此他几乎不会被现代操作系统直接
使用。
此处不予图片展示。Second Chance 策略
- Second Chance 策略是FIFO 的优化版本。
- 操作系统同样需要维护一个队列,该队列用于记录换入物理内存的物理页号。但同时还要为每一个物理页号维护一个访问标志位。
- 如果所访问的页号已经在队列中,则置上其访问标志位。
- 在寻找将要换出的内存页时,该策略优先查看位于队头的页号。此时有两种情况
- 1.如果他的访问标志位没有被置上,则换出该页号所对应的内存页。
- 2.如果他的访问标志位已经被置上,则将该标志位清0,并将该内存页号挪到对尾 ( 将其当成一个最近访问的内存页的页号 ),并从新的对头开始重新寻找要换出的内存页。
- 如果所有的内存页号的访问标志位都被 置上,那么原本处于队头的内存页号将再次回到对头时被换出 ( 此时,所有的标志位都被清 0 )。
我们来看看 Second Chance 策略的执行流程
我们一般认为为一个应用程序分配更多的物理页,则发生换页的次数越少。
但是更多的物理页,就会导致更多的换页( 更低的性能 )。
这种现象 我们称之为 Belady( Belady's anomaly ),该现象可能在操作系统使用 FIFO 和 Second Chance 等页替换策略时发生。LRU 策略
- LRU ( Least Recently Used ) 策略在选择被换出的页时,优先选择最久未被访问的页。
- 过去数条指令频繁访问的页很可能在后续的数条指令中也被频繁访问。
- 实现方法 : 操作系统维护一个链表,按照内存页的访问顺序将内存页号插入链表中 ( 最久被访问的内存页号在链表的首端,而最近访问的内存页号在链表的尾端。)在每次访问内存之后,操作系统把刚刚访问的内存页号调整到链表的尾端;每次都选择换出位于链表首端的页。
MRU 策略
- MRU 策略 与 LRU 策略 相反, MRU ( Most Recently Used ) 策略在替换内存页时,优先换出最久被访问的内存页。
- 该策略认为 : 应用程序不会反复地访问相同的地址。
例如,在一个视频播放器中,每一帧只会被读取一次,不会重复读取。时钟算法策略
- 该算法和Second Chance策略类似,但是这里将换入的物理内存的页号排成了一个时钟的形状。
工作集模型
- 在选择和实现页替换策略时候,操作系统的原则是以最小的算法开销达到尽可能接近 MIN 策略的效果。
- 然后如果选择的替换策略与实际的工作负载不匹配,则有可能导致 颠簸现象( thrashing ),造成严重的性能损失。
工作集模型 能够有效的避免颠簸现象发生,工作集的定义是 : " 一个应用程序在时刻 t 的工作集 W 为他在时间区间[ t - x, t ]使用的内存页集合,也被认为他在未来( 下一段x时间内 ) 会访问的内存页集合 "。
那么如何高效地追踪工作集呢?一种常见的实现方法就是 工作集时钟算法
- 操作系统设置一个定时器,每经过固定的时间间隔,一个设置好的工作集追踪函数就会被调用。
- 该追踪函数 为 每个内存页维护两个状态。上次使用时间和访问位,均被初始化位 0 ,每次被调用,该函数都会检查每个内存页的状态。
- 如果访问位 是 1,则说明在此次 时间间隔 内核页被访问过,于是该函数会把当前系统时间赋值给该内存页的上次使用时间。
- 该方法前提是 CPU 硬件会在程序访问某一个页的时候自动地将对应的访问位设置为1,如果访问位是0,那么就说明在此次时间间隔内该页没有被访问,于是该函数就会计算该页的年龄, 若该页的年龄超过预设的时间间隔 X,那么就不再属于工作集。
- 检查完一个页的状态之后,工作集追踪函数将其访问位设置为0,通过工作集时钟算法或者具有相似设计的算法,操作系统能够有效地预测工作集,从而灵活地进行页替换。
虚拟内存总结
虚拟内存抽象使应用程序能够拥有一个独立而连续的虚拟地址空间,其通过
页表与硬件的配合能够在应用程序透明的前提下自动地进行虚拟地址到物理
地址的翻译。
















