操作系统原理——第四章:非连续式内存分配

1. 为什么需要非连续内存分配

1.1 连续内存分配的不足

  1. 分配给一个程序的物理内存是连续的
  2. 内存利用率低
  3. 有外碎片、内碎片的问题

1.2 非连续内存分配的优点

  1. 一个程序的物理地址空间是非连续的
  2. 更好的内存利用和管理
  3. 允许共享代码与数据(共享库等…)
  4. 支持动态加载和动态链接

1.3 非连续分配分配的缺点

如何建立虚拟地址和物理地址的转换:

  • 软件方案(开销很大)
  • 硬件方案(两种方案:分段、分页)

2. 分段:更好的分离和管理

2.1 程序分段地址空间

在分段技术支持下,应用程序如下图所示:
在这里插入图片描述
通过分段之后有效的隔离开来
在这里插入图片描述
段地址空间的逻辑视图:

在这里插入图片描述

2.2 分段寻址方案

  1. 新概念:一个段:一个内存“块”
    一个逻辑地址空间
  2. 程序访问内存地址需要:一个2维的二元组(s, addr)
    s:段号
    addr:段内偏移
    在这里插入图片描述

2.3 段访问的硬件实现

在这里插入图片描述

3. 分页

段机制用的比较少,主要还是分页机制

3.1 分页地址空间

  1. 划分物理内存至固定大小的帧(Frame):大小为 2 的兵幂,512 / 4096 / 8192
  2. 划分逻辑地址空间至相同大小的页(Page)大小为 2 的幂,512 / 4096 / 8192
  3. 建立方案 → 转换逻辑地址为物理地址(pages to frames):
    ① 页表
    ② MMU / TLB

3.1.1 帧(Frame)

  1. 物理内存被分割为大小相等的帧

  2. 一个内存物理地址是一个二元组(f, o) → (帧号, 帧内偏移):
    帧号 : F位, 共有2^F个帧
    帧内偏移 : S位, 每帧有2^S个字节

  3. 物理地址 = 2^S * f + o

分页和分段的最大区别 : 这里的 S 是一个固定的数, 而分段中的长度限制不定
在这里插入图片描述
例 : 16-bit地址空间, 9-bit(512 byte) 大小的页帧

  • 物理地址 = (3,6)
  • 物理地址 = 2^9 * 3 + 6 = 1542
    在这里插入图片描述
    物理地址 = 2S*f + o
    F=7 S=9 f=3 o=6
    实际物理地址 =2^9 *3+ 6=1536+6=1542

3.1.2 页(Page)

  1. 一个程序的逻辑地址空间被划分为大小相等的页.
  2. 页内偏移的大小 = 帧内偏移的大小
  3. 页号大小 <> 帧号大小
  4. 一个逻辑地址是一个二元组(p, o) → (页号, 页内偏移)
    页号 : P位, 共有2^P个页
    页内偏移 : S位, 每页有2^S个字节
    虚拟地址 = 2^S * p + o
    在这里插入图片描述

3.2 页寻址方案

操作系统维护一张页表, 页表保存了逻辑地址——物理地址之间的映射关系,存储 :页号, 帧号

  • 逻辑地址空间应当大于物理内存空间
  • 页映射到帧
  • 页是连续的虚拟内存
  • 帧是非连续的物理内存(有助于减少碎片的产生)
  • 不是所有的页都有对应的帧
    在这里插入图片描述
    在这里插入图片描述

4. 页表

4.1 页表概述

在这里插入图片描述
页表转换实例,res位0表示物质地址不存在,1表示存在
在这里插入图片描述
分页机制性能问题

  1. 访问一个内存单元需要2次内存访问
    ① 一次用于获取页表项
    ② 一次用于访问数据
  2. 页表可能非常大
    ① 64位机器如果每页1024字节, 那么一个页表的大小会是多少?(2^64 / 2^10 = 2^54 存放不下)
    ② 每一个运行的程序都需要有一个页表
  3. 如何处理?
    ① 缓存(Caching)
    ② 间接(Indirection)访问

4.2 转换后备缓冲区(TLB)

快表(Translation Look-aside Buffer, TLB)
写出的程序尽量具有局部性,减少TLB访问miss
在这里插入图片描述

4.3 二级/多级 页表

  1. 分级机制之下,res为0的对应空间不需要保留
  2. 页表级数越多,访问次数越多,访问需要的时间越长,以时间换取空间
  3. 时间的开销再通过TLB进行缓解
    在这里插入图片描述
    在这里插入图片描述

4.4 反向页表

解决大地址空间问题

目的 : 根据帧号获得页号

反向页表只需要存在一张即可

  • 有大地址空间(64-bits), 前向映射页表变得繁琐. 比如 : 使用了5级页表
  • 不是让页表与逻辑地址空间的大小相对应, 而是当页表与物理地址空间的大小相对应. 逻辑地址空间增长速度快于物理地址空间

4.4.1 基于页寄存器(Page Registers)的方案

存储 (帧号, 页号) 使得表大小与物理内存大小相关, 而与逻辑内存关联减小.

每一个帧和一个寄存器关联, 寄存器内容包括 :

  • resident bit : 此帧是否被占用
  • occupier : 对应的页号 p
  • protection bits : 保护位

实例 :

  • 物理内存大小是 : 4096 * 4096 = 4K * 4KB = 16 MB
  • 页面大小是 : 4096 bytes = 4 KB
  • 页帧数 : 4096 = 4 K
  • 页寄存器使用的空间(假设8 bytes / register) : 8 * 4096 = 32 Kbytes
  • 页寄存器带来的额外开销 : 32K / 16M = 0.2%
  • 虚拟内存大小 : 任意

优势 :

  • 转换表的大小相对于物理内存来说很小
  • 转换表的大小跟逻辑地址空间的大小无关

劣势 :

  • 需要的信息对调了, 即根据帧号可以找到页号
  • 如何转换回来? (如何根据页号找到帧号)
  • 在需要在反向页表中搜索想要的页号

4.4.2 基于关联内存(associative memory)的方案

硬件设计复杂, 容量不大, 需要放置在CPU中

  • 如果帧数较少, 页寄存器可以被放置在关联内存中
  • 在关联内存中查找逻辑页号
    成功 : 帧号被提取
    失败 : 页错误异常 (page fault)
  • 限制因素:
    大量的关联内存非常昂贵(难以在单个时钟周期内完成 ; 耗电)

4.4.3 基于哈希(hash)的方案

哈希函数 : h(PID, p) 从 PID 标号获得页号

在反向页表中通过哈希算法来搜索一个页对应的帧号

  • 对页号做哈希计算, 为了在帧表中获取对应的帧号
  • 页 i 被放置在表 f(i) 位置, 其中 f 是设定的哈希函数
  • 为了查找页 i , 执行下列操作 :
    ① 计算哈希函数 f(i) 并且使用它作为页寄存器表的索引, 获取对应的页寄存器
    ② 检查寄存器标签是否包含 i, 如果包含, 则代表成功, 否则失败
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

平什么阿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值