1. 页面置换的概念

功能:选择被置换的物理页面

设计目标:

  1. 减少页面的调入调出的次数
  2. 将未来或短期内不访问的页面调出

页面锁定:不可以置换的页面

即页表项中的标志锁定位置1的页面(通常是操作系统页面,需要高读写的页面等)

1.1 局部置换

选择范围:当前进程占用的物理页面

分为:

  1. 最优算法
  2. 先进先出算法
  3. 最近最久未使用算法

1.2 全局置换

选择范围:所有可换出的物理页面

分为:

  1. 工作集算法
  2. 置换率算法

2. 三大局部置换解决算法

2.1 最优页面置换算法 optimal

思路: 未来时间不会访问的页面

实现:

  1. 缺页时,计算每个页面下一次访问的时间
  2. 选择未来最长时间访问的页面

特征:

  1. 缺页最少
  2. 实际上无法实现
  3. 因为无法预知
  4. 可以作为其他置换算法的性能评价依据

1

2.2 先进先出算法 FIFO

思路:在内存驻留时间最长的页面进行置换

实现:

  1. 维护一个记录所有位于内存中的逻辑页面链表
  2. 按驻留内存的时间排序,链首最长,链尾最短
  3. 缺页时,选择链首页面进行置换,新页面添加到链尾

特征:

  1. 实现简单
  2. 性能较差,调出的页面可能经常访问
  3. 进程分配物理页面数增加时,缺页不一定减少(Belady现象
  4. 很少单独使用

2

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

思路:选择最长时间没有被引用的页面进行置换

(如某些页面长时间未被访问,在未来可能会长时间不会访问)

实现:

  1. 缺页时,计算每个页面上一次访问的时间
  2. 选择上一次使用到当前时间最长的页面

特征:

  1. 最优置换算法的一种近似

3

2.4 LRU算法的可能实现办法

  1. 页面链表
    1. 按最近一次访问的时间排序的页面链表
    2. 链表首节点是最近访问的页面
    3. 尾节点是最久未使用的页面
  2. 活动页面栈
    1. 访问页面时,将此页号压入栈顶,并在栈内相同的页号抽出
    2. 缺页时,置换栈底的页面

特征:
开销大

用栈实现LRU算法

4

3. 时钟置换算法和最不常用算法

3.1 时钟置换算法 clock (FIFO和LRU的折中版)

思路:仅对页面的访问情况进行大致统计

数据结构:

  1. 在页表项中增加访问位,描述页面在过去一段时间呃访问情况
  2. 各页面组织成环形链表
  3. 指针指向最先调入的页面

算法:

  1. 访问页面时,在页表项记录页面的访问情况(访问位置1)
  2. 缺页时,从指针处开始顺序查找未被访问的页面进行置换

特征:
LRU和FIFO的折中

替换前:

5

替换后:

6

示例:

7

8

改进的clock算法

思路:
减少了修改页的缺页处理开销
算法:
页表项增加修改位
缺页时,修改页面标志位,跳过修改的页面

9

读 ——> 10
写 ——> 11

找置换时:

11 ——> 01
10/01 ——> 00
00 ——> 置换 (然后该页面为10)

10

3.2 最不常用算法 LFU (Least Frequently Used)

思路:
缺页时,置换访问次数最少的页面

实现:

  1. 每个页面设置一个访问计数
  2. 访问每个页面时,访问次数+1
  3. 缺页时,置换计数最小的页面

特征:

  1. 开销大
  2. 解决办法:衰减右移

LRU 和 LFU 的区别

  1. LRU 关注多久未访问,时间越短越好
  2. LFU 关注访问次数,次数越多越好

11

4. Belady现象 和 局部置换算法的比较

4.1 Belady现象

现象:
采用FIFO等算法时,可能出现分配的物理页面数增加,缺页次数反而升高的异常现象

原因:

1. FIFO算法的置换特征与进程访问内存的动态特征矛盾
2. 被它置换出去的页面并不一定是进程近期不会访问的

物理页数为 3

12

+1后,物理页数为 4

13

证明:存在 belady现象

LRU算法没有Belady现象!

4.2 LRU,FIFO和clock算法的比较

LRU 和 FIFO 本质上都是先进先出的思路

  1. LRU依据页面的最近访问时间排序
  2. LRU需要动态调整顺序(维护一个栈…)
  3. FIFO依据页面进入内存的时间排序
  4. FIFO的页面进来后是固定不变的

LRU 可以退化成FIFO

如:1,2,3,4,5,6,1,2,3

比较

  1. LRU 性能好,开销大
  2. FIFO 性能差,但会发生Belady现象
  3. clock 是他们的折中
    1. 页面访问时,不动态调整页面在链表中的顺序,仅作标记
    2. 缺页时,再把它移动到链表末尾

5. 全局页面置换算法

局部置换算法没有考虑进程访问的差异

思路:全局置换算法为进程分配可变数目的物理页面

问题?

  1. 进程再不同阶段的内存需求是变化的
  2. 分配给进程的内存在需要不同阶段有所变化
  3. 全局置换算法需要确定分配给进程的物理页面数

5.1 工作集置换算法

工作集:一个进程当前正在使用的逻辑页面集合,可表示为二元函数W(t, delta)

14

示例:

15

工作集的变化:

16

工作集置换算法

思路:换出不在工作集的页面

窗口大小 t :
当前时刻前t个内存访问的页引用是工作集,t被称为窗口大小

实现方法:

  1. 访存链表:维护窗口内的访存页面链表
  2. 访存时,换出不在工作集的页面,更新访存链表 (复杂的地方)
  3. 缺页时,换入页面,更新访存链表

缺点:
开销大

17

5.2 缺页率算法

缺页次数 / 内存访问次数 or 缺页平均时间间隔的倒数的平均值

影响的因素:

  1. 页面置换算法 (可控制的)
  2. 分配给进程的物理页面数目
  3. 页面大小
  4. 程序的编写方法

18

缺页率置换算法 图示:

19

实现:

  1. 访存时,设置引用标志
  2. 缺页时,计算从上次缺页时间T_last到现在T_current的时间间隔
    1. T_current - T_last > T 置换所有在[T_last, T_current]的页面
    2. T_current - T_last < T 增加缺失页放入常驻集中

20

6. 抖动和负载控制

6.1 抖动问题

抖动:

  1. 进程中物理页面太少,不能包含工作集
  2. 造成大量缺页,频繁置换
  3. 进程运行速度变慢

产生抖动的原因:

  1. 驻留在内存的进程数目增加,分配给每个进程的物理页面减少,缺页率上升

需要在并发和缺页率之间达到一个平衡

6.2 负载控制

调节并发进程数 MPL 来进行系统负载控制

21

评论