十一、内存分配

111 阅读4分钟

内存分配

连续分配管理方式

  • 单一连续分配:早期分配方式,内存中只加载一个进程,从空闲内存开始为进程分配连续空间
  • 固定分区分配:内存可以加载多个进程后,早期使用的分配方式。内存空间被分配成固定大小的分区,这些区域大小不一定相同。另外有一张表存储了内存分区的信息:分区大小、起始地址、分配状态。在加载进程时,需要先查表找到合适分配的区域
  • 动态分区分配:按照进程的需求动态分配分区
    • 使用空闲分区表/空闲分区链记录内存分区的信息。不论表还是链表,都只记录空闲的分区
    • 为进程分配分区的算法:
      • 首次适应算法:从低地址开始查找合适空间
      • 最佳适应算法:将分区按照大小排序,从最小容量分区开始查找合适空间
      • 最坏适应算法:与最佳适应算法相反,从最大容量分区开始查找
      • 临近适应算法:从上次查找的分区开始往后查找
    • 回收动态分区时,相邻的空闲分区会进行合并

非连续分配和管理

基本分页存储管理方式

将内存划分成大小4K的一个个固定分区,这些分区称为页框

  • 在进程加载到内存前,按照页的大小,将进程所需的内存大小分页,并且标上页号
  • 在页表这个数据结构中存储了进程分页的信息,包括分页个数,页号等
  • 在页表中也存储了进程分页与内存分页的一一对应关系
  • 页表存储在PCB中
  • 基本地址变换机制:根据逻辑地址找到对应的物理地址
    • 物理地址=逻辑页号对应的内存页号+偏移量
    • 逻辑页号=逻辑地址/页框大小
    • 偏移量=逻辑地址%页框大小
  • 具有快表的地址变换机构:页表不存在内存中,而是放在缓存里
    • 快表中只存放页表的部分内容,这部分内容是之前访问过的页表内容
    • cpu会先查询快表,如果没有,再查询页表
  • 两级页表
    • 两级页表是为了解决页表过大不好存储以及动态内存加载的问题
    • 两级页表分为页目录表(一级页表)和页表(二级页表),页目录表存储二级页表的地址,二级页表存储进程物理地址
    • 两级页表工作机制
      • 将逻辑地址分成三部分,高10位是一级页号,后10位是二级页号,最后12位是偏移量
      • 从PCB中读取页目录表,根据一级页号查找二级页表位置
      • 根据二级页号查找内存块号,加偏移量计算物理地址
    • 两级页表中的一级页表共有1024条记录,二级页表中的每个页表也只存1024条记录,这样页表就可以占满一个页框

基本分段存储管理

  • 将进程分成多段,每段大小不一定一样,每段都有编号
  • 有段表存储进程分段和内存地址的映射关系
  • 地址变换机构:根据段号找到对应内存的起始地址,然后加上段长,就是这段的终止地址
  • 段的共享和保护:进程在加载时除了自身代码,还有依赖库进程。在进程分段时,将依赖库进程分成一段,加载到内存中。这块依赖库进程可能还被其他进程依赖,所以在加载其他进程时,依赖库进程段可以被共享
  • 段表存放在寄存器中

段页式管理

  • 进程分段
  • 使用段页表存储信息,包括:段号、页表长度(段占用的页框个数)、页表存放块号
  • 使用页表存储页号与块号信息
  • 逻辑地址中高16位是段号,后4位是页号,最后12位是页内地址