【操作系统】Operation System-第4章-连续内存分配 & 非连续内存分配

操作系统—连续内存分配 & 非连续内存分配

image-20220523164331726

1. 连续内存分配

内存碎片问题

image-20220519163823463

分区的动态分配

简单的内存管理方法:

  • 当一个程序准许运行在内存中时,分配一个连续的区间

  • 分配一个连续的内存区间给运行的程序以访问数据

image-20220519170324420

分区的动态分配方式有以下三种 :

  1. 第一适配:在内存中找到第一个比需求大的空闲块,分配给应用程序
  2. 最佳适配:在内存中找到最小、最适合的空闲块,分配给应用程序
  3. 最差适配:在内存中找到最大的空闲块,分配给应用程序

最先匹配(First Fit Allocation)策略

image-20220519184256575

原理 & 实现

  • 按地址顺序排序的空闲块列表
  • 分配需要寻找一个合适的分区
  • 重分配需要检查 是否自由分区可以合并于相邻的空闲分区(若有)

优点

  • 简单
  • 易于产生更大空闲块,在高地址空间有大块的空闲分区

缺点

  • 外部碎片
  • 不确定性
  • 分配大块时较慢

最佳匹配(Best Fit Allocation)策略

image-20220519185558307

为了避免分割大空闲块,为了最小化外部碎片产生的尺寸。

原理 & 实现

  • 按尺寸排序的空闲块列表
  • 分配需要寻找一个合适的分区
  • 释放时,查找并且合并临近的空闲分区(如果找到)

优点

  • 大部分分配的尺寸较小时,效果很好
  • 可避免大的空闲分区被拆分
  • 可减小外部碎片的大小
  • 相对简单

缺点

  • 外部碎片
  • 释放分区较慢
  • 容易产生很多无用的微小碎片

最差匹配(Worst Fit Allocation)策略

image-20220519203945834

为了避免有太多微小的碎片。

原理 & 实现

  • 按尺寸排序的空闲块列表
  • 分配很快(获得最大的分区)
  • 释放时,检查是否可与临近的空闲分区合并,进行可能的合并,并调整空闲分区列表顺序

优点

  • 中等大小的分配较多时,效果最好
  • 避免出现太多的小碎片

缺点

  • 外部碎片
  • 释放分区较慢
  • 容易破坏大的空闲分区,因此后续难以分配大的分区

分配方式的区别

分配方式 第一适配分配 最优适配分配 最差适配分配
原理
&
实现
1. 按地址排序的空闲块列表
2. 分配需要寻找一个合适的分区
3. 重分配需要检查是否可以合并相邻空闲分区
1. 按尺寸排序的空闲块列表
2. 分配需要寻找一个合适的分区
3. 重分配需要检查是否可以合并相邻空闲分区
1. 按尺寸排序的空闲块列表
2. 分配差距最大的分区
3. 重分配需要检查是否可以合并相邻空闲分区
优势 简单 / 易于产生更大空闲块 比较简单 / 大部分分配是小尺寸时高效 分配很快 / 大部分分配是中尺寸时高效
劣势 产生外部碎片 / 不确定性 产生外部碎片 / 重分配慢 / 产生很多没用的微小碎片 产生外部碎片 / 重分配慢 / 易于破碎大的空闲块以致大分区无法被分配

三种分配方式并无优劣之分,因为我们无法判断内存请求的大小。

碎片整理

可以看到的是,三种分区动态分配的方式都会产生外部碎片,因此我们可以对碎片进行一定的整理来解决碎片问题。

压缩式碎片整理

紧凑(compaction)

  • 重置程序以合并孔洞(碎片)

  • 要求所有程序是 动态可重置的

  • 问题 :

    ➢ 何时重置?(在程序处于等待状态时才可以重置)

    ➢ 开销(内存拷贝:重定位)

image-20220519205124001

交换式碎片整理

分区对换(Swapping in/out)

  • 运行程序需要更多的内存时,抢占等待的程序并回收它们的内存,以增大可用内存空间

image-20220519205308691

  • 问题 :

    ➢ 哪些程序应该被回收?

image-20220519211346479

伙伴系统(Bubby System)

伙伴系统比较好的折中了分配和回收过程当中 合并和分配块位置的 碎片问题。

image-20220523161112870

伙伴系统的实现

image-20220523161129100

伙伴系统中的内存分配

image-20220523161149771


image-20220523164935390

目前在我们用到的Linux、 Unix都有 Buddy System 的实现,它是用来做内核里的存储分配。

既然选择了连续,就避免不了产生碎片。

2. 非连续内存分配

连续内存分配的缺点

  • 分配给一个程序的物理内存是连续的
  • 内存利用率较低
  • 有外碎片 / 内碎片的问题

能否通过新的一些手段来改善这些情况?=> 非连续内存分配。

非连续内存分配的优点

  • 一个程序的物理地址空间是非连续的

  • 更好的内存利用和管理

  • 允许共享代码与数据(共享库等…)

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

非连续内存分配的缺点

建立虚拟地址和物理地址的转换难度大

  • 软件方案(开销相当大)

  • 硬件方案(采用硬件辅助机制)

    ➢ 分段(Segmentation)

    ➢ 分页(Paging)

分段(Segmentation)

  • 程序的分段地址空间
  • 分段寻址方案

image-20220520131314512

  • 段: 计算机程序是由各个组成的:

    ➢ 在代码执行方面会看到有主程序、子程序,还有共享的一些库 形成代码不同的分段

    ➢ 数据方面:栈段、堆段 还有一些共享的数据段

    ➢ 不同的段之间有不同的属性

  • 分段: 更好的分离和共享

程序的分段地址空间如下图所示 :

image-20220520131458299

把左边运行程序的逻辑地址空间看成一个连续一维的线性数组,通过段机制的映射关系把不同的内存块(如:代码、数据、堆、栈)分别映射到不同的内存中的段,可以看到映射到物理地址空间后位置不一样,变得不连续了。

image-20220520132128934

分段寻址方案

image-20220520133011285


image-20220520162553522

段表 在寻址之前操作系统就会建立好,之后段机制就可以正常工作了。

分页(Paging)

  • 分页地址空间
  • 页寻址方案

页式存储管理

页帧(帧、物理页面,Frame,Page Frame)

  • 把物理地址空间划分为大小相同的基本分配单位(帧)
  • 大小是2的幂,e.g.,512 / 4096 / 8192

页面(页、逻辑页面,Page)

  • 把逻辑地址空间也划分为相同大小的基本分配单位(页)
  • 大小是2的幂,e.g.,512 / 4096 / 8192
  • 帧和页的大小必须是相同的

页面到页帧(pages to frames → 建立方案)

  • 转换逻辑地址为物理地址
  • 页表
  • MMU / TLB

帧(Frame)

  • frame-number:帧号
  • off-set:帧内偏移

image-20220520164233625

例子 : 16 − b i t 16-bit 16bit 地址空间, 9 − b i t ( 512 b y t e ) 9-bit(512 byte) 9bit(512byte) 大小的页帧 物理地址 = ( 3 , 6 ) (3, 6) (3,6) 物理地址 = 2 9 ∗ 3 + 6 = 1542 2^9 * 3 + 6 = 1542 293+6=1542

image-20220520172309062

分页和分段的最大区别 : 这里的 S 是一个固定的数,而分段中的长度限制不定

页(Page)

  • page-number:页号(跟帧号可能不同)
  • off-set:页内偏移(跟帧内偏移一样)

image-20220520173254343

页寻址机制

image-20220520173519599

页式存储中的地址映射

一般情况逻辑地址空间要大于物理地址空间。

映射到物理地址空间 存放是不连续的,带来的好处是有助于减少碎片的产生。

image-20220520174017322

页表(Page Table)

页表结构

其实就是一个大数组,它的索引 i n d e x index index 指的是 p a g e − n u m b e r page-number pagenumber(页号),索引对应的内容是 f r a m e − n u m b e r frame-number framenumber(帧号),得到帧号后再叠加上 o f f − s e t off-set offset 得到物理地址。

还有一些内容: b i t bit bit,比如 r e s i d e n t   b i t resident \ bit resident bit 表示这个页表项是否合法(对应在物理地址中是否存在), 0 0 0 代表不合法, 1 1 1 代表合法。

image-20220520175735222

地址转换的实例

image-20220520175659760

分页机制的性能问题

空间代价、时间开销

  • 访问一个内存单元需要2次内存访问

    ➢ 一次用于获取页表项

    ➢ 一次用于访问数据

  • 页表可能非常大

    ➢ 64位机器如果每页1024字节,那么一个页表的大小会是多少?( 2 64 / 2 10 = 2 54 2^{64} / 2^{10} = 2^{54} 264/210=254 放不下)

    ➢ 每一个运行的程序都需要有一个页表

  • 如何处理?

    ➢ 缓存(Caching)

    ➢ 间接(Indirection)访问

快表TLB:解决时间问题

快表(Translation Look-aside Buffer,TLB)

Translation Look-aside Buffer(TLB)是一个缓冲区,CPU中的MMU(内存管理单元)都有一个 快表 TLB 的特殊区域。

TLB表项本身是由一种快速查询的存储器:相关存储器 实现的,它的速度很快,可以并发的进行查找,但容量是有限的;可以将经常访问的页表项存放在这里,提升访问速度;

当CPU得到一个逻辑地址的时候,首先会去TLB中查,如果查到这个key => p 则直接返回对应的value => f;没查到再去页表中查。

image-20220520182407860

二级 / 多级页表:解决空间问题

时间换空间

二级页表
  • 将页号分为两个部分,页表分为两个,一级页号对应一级页表,二级页号对应二级页表。
  • 一级页号查表获得在二级页表的起始地址,地址加上二级页号的,在二级页表中获得帧号
  • 节约了一定的空间,在一级页表中如果 r e s i d e n t b i t = 0 resident bit = 0 residentbit=0,可以使得在二级页表中不存储相关 i n d e x index index,而只有一张页表的话,这一些 i n d e x index index 都需要保留。

image-20220520184452543

多级页表

image-20220520192606369

反向页表(inverted page table)

有没有一种方法使得页表大小与 逻辑地址大小 没有那么大的关系,尽量与 物理地址大小 建立对应关系?——反向页表

image-20220520193444637

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

image-20220520193633025

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

image-20220520193920668


image-20220520195722980

那就需要下面的方案来实现:

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

就是在上方TLB中提到的相关存储器,并行查找,效率很快。

image-20220520200127109

设计成本太大,硬件逻辑复杂,容量不大,需要放置在CPU中。

image-20220520200753802

基于哈希(hash)查找的方案

image-20220520201402890

  • 在哈希函数的基础上再加一个参数 P I D PID PID,标记当前运行程序的编号,根据 h ( P I D , p ) h(PID,p) h(PID,p) 作为 i n p u t input input 来设计出一个比较简洁的哈希函数,算出它对应的 f r a m e − n u m b e r frame-number framenumber
  • 这种方式可以有效缓解映射的开销,需要硬件帮助,但会出现哈希冲突,用上面的 P I D PID PID 解决。

image-20220520202205602


image-20220520202224553

这种方式还是需要把反向页表放到内存中,做哈希计算时也需要到内存中取值,内存的开销还是很大,所以还需要有一个类似TLB的机制缓存起来,降低访问的时间。

目前来说,这种机制只在高端CPU中存在,好处:

  • 容量可以做的很小,只和物理空间关联
  • 对于之前的结构,每一个运行程序都需要有一个 p a g e   t a b l e page \ table page table,但对于这种反向结构,整个系统只需要一个,因为它用的是物理内存的帧号作为 i n d e x index index 而建的表,而这个表与我们有多少个进程无关,所以它占的空间节省很多;但它是有代价的,它需要以一种很高速的哈希计算、硬件处理机制、高校函数以及解决冲突的机制才可以使访问的效率得到保障。
  • 这种机制 有硬件、相应的操作系统软件配合 可以在空间和时间上取得比较好的结果。

段页式存储管理的需求

  • 段式存储在内存保护方面有优势,页式存储在内存利用和优化转移到后备存储方面有优势。
  • 段式存储、页式存储能否结合?

段页式存储管理

image-20220520202910803

段页式存储管理中的内存共享

image-20220520202923994

整理自 【清华大学】 操作系统

猜你喜欢

转载自blog.csdn.net/weixin_53407527/article/details/124891795