非连续分配管理

  • 支持多道程序的两种连续分配方式的缺点
    • 固定分区分配 : 缺乏灵活性, 产生了许多无法利用的内部碎片
    • 动态分区分配 : 当产生了许多外部碎片时, 需要采用"紧凑"技术, 时间代价高

如果允许将一个进程分散地装入到许多不相邻的分区中, 便可充分利用内存, 而无需再进行“紧凑” ---- 分连续分配方式

操作系统[系统学习八]

基本分页存储管理

  • 思想 : 把内存划分为一个个相等的小分区, 然后按照分区大小将进程拆分成一个个小部分.
    操作系统[系统学习八]
  • 页框 : 内存空间划分的一个个大小相等的分区
  • 页框号 : 每个页框的编号, 从0开始 (低地址开始)
  • 页面 : 将用户进程的地址空间划分为和页框大小相等的一个个区域
  • 页号 : 页面的编号, 从0开始
  • 进程的最后一个页面可能没有页框大, 因此页框不能太大, 否则可能产生过大的内部碎片
  • 进程的页面, 和内存的页框一一对应, 页面不必连续存放, 也不必按先后顺序.
    操作系统[系统学习八]

如何实现地址转换

  • 采用分页技术后, 进程的地址空间会被分为一个个页面, 这些页面离散的, 不按顺序地放入内存的各个页框当中. 因此逻辑地址->物理地址的转换, 成了需要解决的第一个问题

  • 连续分配中采用动态重定位进行地址转换

    • 运行时进行地址转换, 一个重定位寄存器记录进程的物理首地址. 实际地址 = 逻辑地址 + 重定位寄存器中的物理首地址
    • 模块在内存中的起始地址 + 目标内存单元相对于起始位置的偏移量

操作系统[系统学习八]
操作系统[系统学习八]

  • 前20位对应页号, 后12位对应页内偏移量
    操作系统[系统学习八]
    操作系统[系统学习八]

  • 如果每个页面大小为2^kB, 用二进制表示逻辑地址时, 末尾k位是 页内偏移量 , 其余部分就是页号

操作系统[系统学习八]

页表

  • 为了能知道进程的每个页面在内存中的存放位置, 操作系统要为每个进程建立一张页表
    • 一个进程对应一张页表
    • 一个页面对应页表中的一个页表项
    • 每个页表项由“页号” 和 “块号” 组成
    • 页表记录进程页面实际存放的内存块之间的关系
    • 每个页表项的长度是相同的, 页号是"隐含"的

操作系统[系统学习八]
为什么每个页表项的长度相同, 页号是隐含的

  • “隐含” 是指不需要显示存储页号, 第几个页块也就对应了第几个页号, 所以内存页表中只存储了块号地址. 想要直到M号页面对应的物理起始地址, 直接用M*3+页表起始地址, 找到M号页面所属的页表项的位置, 然后读取其中的块号, 然后用 块号 * 页面(页框)大小, 即可知道该页面实际存放的物理地址.
  • 操作系统[系统学习八]

总结

操作系统[系统学习八]

基本地址变换机构(页表寄存器)

  • 分页存储管理 : 将内存划分为一个个大小相同的分区, 称为“页框”, 将进程的地址空间划分为相同大小的一个个模块, 称为“页面”, 页面和页框一一对应, 这些页面离散的, 不按顺序地存储在也页框中. 寻址的时候, 只需要根据逻辑地址, 计算出所在的页号, 然后查找页表取出该页号的页面在内存中存放的物理首地址. 然后求出逻辑地址在该页面的偏移量. 用首地址+偏移量. 就是该逻辑地址的物理地址. 一个进程对应一个页表, 一个页面对应一个页表项. 页表项由页号和块号组成. 页号是隐含的. 逻辑地址对应的页号 由 逻辑地址 / 页面大小. 偏移量 逻辑地址 % 页面大小.
  • 系统中会设置一个 页表寄存器(PTR), 存放页表在内存中的起始地址F 和 页表长度M,
    • 进程未执行时, 页表的起始地址 和 页表的长度(多少个页面) 放在进程控制块(PCB)中, 当进程被调度时, 操作系统内核会把他们放到页表寄存器中
      • (因为是动态重定位的方式进行地址转换)
        • (所以说页表寄存器也只有一个, 所有继承共享, 运行的进程才能占用)

操作系统[系统学习八]
操作系统[系统学习八]
操作系统[系统学习八]
操作系统[系统学习八]

  • 因为页内偏移量是末尾多少位, 块号是前面多少位, 两个可以直接拼接在一起.
  • 1023 是 011 11111111; 1024 是 100 00000000

操作系统[系统学习八]

  • 页内偏移量占10位, 说明最大是 11 11111111个存储单元, 所以一个页面大小100 00000000存储单元. 因为按字节寻址, 所以一个存储单元大小是一个字节. 所以一个页面大小1kB. 如果是按字存储, 那么一个页面大小就是2kB.

  • 分页存储管理, 只需要知道页面大小, 就可以知道逻辑地址对应的物理地址. 所以说地址是一维的.

    • 页号 : 逻辑地址 / 页面大小
    • 偏移量 : 逻辑地址 % 页面大小
    • 块大小 : 页面大小
    • 页表起始地址系统分配,
    • 块号 : 页表起始地址 + 块大小 + 页号
    • 物理地址 : 块号 * 块大小(页面大小)
  • 需要注意对页号的越界检查 (页号和页表长度进行比较, 只有小于 才合法)

  • 页表也是存储在内存中的, 也需要考虑碎片问题

    • 如果一个页表项长度3B, 而页面大小4kB, 会有1B的内部碎片. 同时对页表项存放的物理地址的寻址也会进行特殊处理
    • 所以为了寻址方便, 通常会让一个页表项占更多的字节.
      操作系统[系统学习八]

总结

  • 整个寻址过程中, 两次访问内存
    • 第一次 : 查询页表
    • 第二次 : 访问目标存储单元
      操作系统[系统学习八]

具有快表的地址变换机构

操作系统[系统学习八]

局部性原理

  • 时间局部性 : 如果执行了程序的某条指令, 不久将来, 这条指令很可能再次被执行. 如果访问了某个数据, 不久将来, 这个数据会再次被访问. ( 因为程序中存在大量循环 )

  • 空间局部性 : 一旦程序访问了某个存储单元, 不久之后, 其附近的存储单元也很有可能被访问 (因为很多数据在内存中是连续存放的)

  • 在基本地址变换机构中, 每次访问一个逻辑地址, 都需要查询内存中的页表, 由于局部性原理, 可能连续多次查到的都是同一个页表项. 既然如此, 能否利用这个特性减少访问页表的次数?

操作系统[系统学习八]

快表

  • 快表: 联想寄存器(TLB), 是一种访问速度比内存快很多的高速缓冲存储器. 用来存放当前访问的若干页表项, 以加速地址变换的过程. 与此对应, 内存中的页表常称为 慢表

操作系统[系统学习八]

引入快表后, 地址变换过程

  • 默认先查询快表, 失败后在查询慢表
    操作系统[系统学习八]

总结

  • 如果快表查询没有命中, 需要查询慢表, 同时把对应的页表项复制一份到快表
  • 访问内存速度是比访问快表慢的

操作系统[系统学习八]

两级页表

操作系统[系统学习八]

单级页表存在的问题

操作系统[系统学习八]
操作系统[系统学习八]

  • 页表必须连续存放(方便根据页号查询), 因此当页表很大时, 需要占用很多个连续的页框

  • 没有必要让整个页表常驻内存, 因为进程在一段时间内可能只需要访问某几个特定页面(局部性原理)

  • 我们是如何解决进程在内存中必须连续存放的问题的

    • 将进程地址空间分页, 用一个页表记录个页面的位置
  • 同样思路, 用于解决“页表必须在内存中连续存放的问题”, 把连续存放的页表再也页. 然后用一个数据结构, 记录页表在内存中的位置

    • 将长长的页表进行分组, 使每个内存块刚好放入一个分组 (上个例子中, 每个页面4kB, 每个页表想4B, 每个页框可存放1k个页表项, 因此每1k个连续的页表项为一组, 每组刚好占用一个内存块, 再将各组离散地放到不同内存块)
    • 要为离散存储的页表再建立一张页表, 称为页目录表, 外层页表, 顶层页表

两级页表 (解决连续占用内存问题)

操作系统[系统学习八]
操作系统[系统学习八]
操作系统[系统学习八]

  • 一级页表内存块号 指的是 对应的二级页表在内存中存放的位置. 取出来后, 继续在这个二级页表中查询指令存放的块号.

虚拟存储技术 (解决整个表常驻内存的问题)

操作系统[系统学习八]

需要注意的细节

  • 若采用多级页表机制, 各级页表的大小不能超过一个页面
  • 单级页表只需要进行两次内存访问
  • 两级页表需要进行三次, 虽然解决了单级页表的存在的两个问题, 使得内存利用率提升, 相对应付出的代价是, 多一次访问内存, 花费更长的时间
    • 没有快表, n级页表, 需要访问n+1次内存
      操作系统[系统学习八]

总结

操作系统[系统学习八]

基本分段存储管理

操作系统[系统学习八]

分段

  • 进程的地址空间, 按照程序自身的逻辑关系划分为若干个段, 每个段都有一个段名(低级语言中, 程序员使用段名来编程), 每段从0开始编址
  • 内存分配规则 : 以段为单位进行内存分配, 每个段在内存中占据连续存储空间, 但各段之间可以不相邻

操作系统[系统学习八]

  • 段号的位数 决定了 每个进程最多可几个段
  • 段内地址的位数 决定了 每个段的最大长度是多少

操作系统[系统学习八]

段表

  • 程序分为多个段, 各段离散存储在内存中, 为了保证程序的正常运行, 就必须能从内存中找到各逻辑段存放的位置, 为此需要一张段映射表, 简称“段表”
    • 每个段对应一个段表项, 其中记录了该段在内存中的起始位置(基址) 和 段的长度
    • 各个段表项的长度是相同的, 因此段号可以隐含, 不占存储空间.

操作系统[系统学习八]

地址变换

  • 进程未上处理机运行时, 段表在内存的起始地址 和 段表长度 存放在PCB中. 进程上处理机运行后, 这些信息会转移到段表寄存器中(一个物理硬件)
  • 分页存储中, 各页大小一样, 不需要对页内偏移量是否越界进行检查; 而分段存储中, 各段大小不同, 需要对段内偏移量是否越界进行检查 (和段长比较)
    操作系统[系统学习八]
    操作系统[系统学习八]

分段, 分页管理的对比

  • 分页地址转换是一维的 : 只需要一个页面大小
  • 分段地址转换是二维的 : 需要段号, 和段内偏移量 (段名 和 助记符)

操作系统[系统学习八]

操作系统[系统学习八]
操作系统[系统学习八]
操作系统[系统学习八]

总结

操作系统[系统学习八]

段页式管理

操作系统[系统学习八]

分页, 分段的优缺点分析

操作系统[系统学习八]

分段 + 分页 = 段页式

  • 地址结构也是二维的 : 用户只需要提供段号 和 段内地址 (系统自动将段内地址 拆分成 页号, 页内偏移量)
    操作系统[系统学习八]
    操作系统[系统学习八]

段表, 页表

操作系统[系统学习八]

  • 一个进程对应一个段表, 多个页表

地址转换过程

  • 需要检查页号是否越界, 因为各段长度不等, 页表程度也就不同.
    操作系统[系统学习八]

总结

操作系统[系统学习八]

相关文章: