0%

2.2:物理内存管理——非连续

背景

连续分配的缺点:

  • 物理内存必须连续

  • 存在外碎片和内碎片

  • 内存分配的动态修改困难

  • 内存利用率较低

非连续分配的设计目标

  • 目标:提高内存利用效率和管理灵活性

  • 允许一个程序使用非连续的物理地址空间

  • 允许共享代码与数据

  • 支持动态加载和动态链接

非连续分配需要解决的问题

  • 何实现虚拟地址和物理地址的转换(不同的逻辑地址可能位于不连续的物理区域中)

    • 软件实现(灵活,开销大)

    • 硬件实现(够用,开销小)

  • 如何选择非连续分配中的内存分块大小

    • 段式存储管理(segmentation):块大
    • 页式存储管理(paging):块小

段式存储

进程有哪些段

  • 代码段(公用库代码段、子模块代码段、主代码段)

  • 堆栈段(stack)

  • 堆数据(heap)

  • 初始化数据段

  • BSS段(存放未初始化的全局变量)

段的概念

  • 段表示访问方式和存储数据等属性相同的一段地址空间

  • 对应一个连续的内存“块”

  • 若干个段组成进程逻辑地址空间

  • 段访问:逻辑地址由二元组(s,addr)表示;“段基址+段内偏移”

段访问的硬件实现

  • 首先从逻辑地址中得到段号和偏移量

  • 在段表中查找段号,得到段基址和段长度

  • 由MMU来判断偏移量是否合法(偏移量是否大于段长度)

  • 得到物理地址,在物理内存中查找相应内容

页式存储

页式存储概念

页帧(帧是物理的)

  • 把物理地址空间划分为大小相同的基本分配单位

  • 2的n次方,如512,4096,8192,4k是常用大小

  • 地址可以表示成二元组(f,o);“帧基址(帧号*帧大小)+帧内偏移”

页面(页是逻辑的)

  • 把逻辑地址空间也划分为相同大小的基本分配单位

  • 帧和页的大小必须是相同的

页表

保存页号与帧号之间的映射关系

页表结构

  • 每个进程都有一个页表

  • 随进程运行状态而动态变化(可以动态调整内存空间大小)

  • 页表基址寄存器:PTBR(存放页表起始位置)

页表项的组成

每个页面对应一个页表项

  • 帧 号:f

  • 存在位:逻辑页面是否存在与之对应的物理帧(有些逻辑页没有对应的物理帧)

  • 修改位:对应的页面中的内容是否被修改了

  • 引用位:在过去一段时间内是否访问过页中的某一个存储单元

页式存储的性能问题

  • 访问一个内存单元需要2次内存访问:第一次访问:获取页表项,第二次访问:获取数据

  • 页表可能非常大:64位机器如果每页1024字节,则页表的大小为2^54*8

页式存储的性能优化

快表(TLB):缓存
  • 缓存近期访问的页表项

  • 关联存储器:有一组key,可以并行地查找所有表项,得到匹配项

  • 快表位于CPU中,所以它的速度快、成本高、功耗大

  • 如果TLB未命中,再访问页表,对应的表项被更新到TLB中

多级页表:
  • 通过间接引用将页号分成k级,建立页表“树”。

  • 减少了空页表项,节约空间。但大地址空间(64-bits)系统,多级页表变得 繁琐。

反置页表:hash
  • 页表项与帧做对应

  • 页寄存器(一个帧对应一个页寄存器)的内容包括

    • 使用位(Residence bit):此帧是否被进程占用

    • 占用页号(Occupier):对应的页号p

    • 保护位(Protection bits):约定这一页的访问方式,可读,可写……

  • 页寄存器中的地址转换:对逻辑地址进行*Hash映射,以减少搜索范围

  • 页寄存器搜索步骤

    • 对逻辑地址进行Hash变换

    • 在快表中查找对应页表项

    • 有冲突时遍历冲突项列表

    • 查找失败时,产生异常

  • 反置页表的优缺点

    • 优点:页表小

    • 缺点:需要搜索页寄存器

段页式存储

  • 什么是段页式存储管理

    • 在段式存储管理基础上,给每个段加一级页表

    • 逻辑地址:段号+若干个页号+页内偏移

    • 物理地址:帧号+页内偏移

  • 段页式存储管理中的内存共享(同表):通过指向相同的页表基址,实现进程间的段共享,共享段指向同一个页表