简单易懂,什么是连续分配管理方式
连续分配管理方式。这个策略的核心思想非常直观:要给一个进程分配内存,就必须给它一整块连续的、没有被分割的内存空间。
我们用一个非常贴切的比喻来理解这几种方式的演进:一个电影院的座位安排。
- 内存:电影院里的所有座位。
- 进程:一个个想要看电影的观众(或观影团体)。
- 分配内存:给观众安排座位。
1. 单一连续分配 - “包场”模式
这是最古老、最简单的座位安排方式。
- 工作方式:
- 整个电影院被简单地划分为两个区域:“员工专用区” (系统区) 和 “观众席” (用户区)。
- 任何时候,只允许**一个观影团体(一个用户程序)**进入“观众席”。这个团体可以独占所有的观众座位,无论他们来了多少人。
- 优点:
- 管理简单:管理员只需要记录“有人”或“没人”,无需复杂的座位表。
- 无外部碎片:因为要么整个观众席都被占用,要么都空着,不会出现“座位之间有零散空位,但坐不下新团体”的情况。
- 缺点:
- 利用率极低:如果只来了一个人看电影,他也占了整个观众席,其他几百个座位都空着浪费了。
- 产生内部碎片:分配给团体的空间(整个观众席)远大于其实际需要的空间(只来了一个人),这些已分配但未被使用的空间,就叫做内部碎片。
- 不支持并发:一次只能服务一个团体,效率低下。
一句话总结:简单粗暴的包场模式,只适用于早期的单用户、单任务系统。
2. 固定分区分配 - “包厢”模式
为了提高利用率,电影院老板决定进行改造,引入“包厢”的概念。
- 工作方式:
- 在营业前,老板就把整个观众席划分成了若干个大小固定的“包厢”(分区)。
- 每个包厢一次只能给一个观影团体使用。
- 管理员手里有一张**“包厢登记表”(分区说明表)**,记录了每个包厢的大小、位置和是否有人。
- 两种包厢设计:
- 大小相等:所有包厢都一样大。比如都设为5人座。管理简单,但缺乏灵活性(来6个人的团体就坐不下,来2个人的团体就浪费3个座位)。
- 大小不等:有2人座、5人座、10人座等多种包厢。灵活性稍高,可以根据团体人数安排一个“差不多”大小的包厢。
- 优点:
- 支持多道程序:可以同时服务多个观影团体,大大提高了电影院的并发度。
- 实现简单,无外部碎片:因为包厢是预先划好的,不会产生无法利用的零散座位。
- 缺点:
- 产生内部碎片:一个3人的团体被安排进一个5人座的包厢,就会浪费2个座位。这种包厢内部的浪费,就是内部碎片。
- 缺乏灵活性:如果来了一个20人的超大团体,而最大的包厢只有10人座,那这个团体就无法入场(除非他们愿意分开坐,但这不符合“连续分配”的原则)。
一句话总结:预设好的包厢模式,支持了并发,但因大小固定而导致浪费和不灵活。
3. 动态分区分配 - “自由隔断”模式
为了追求极致的灵活性和利用率,电影院老板采用了最先进的“自由隔断”模式。
- 工作方式:
- 整个观众席一开始是一整块连续的空闲区域。
- 当一个5人的团体到来时,管理员会现场从空闲区域中划出刚刚好5个座位给他们,并用隔板围起来,形成一个临时分区。
- 剩下的区域仍然是连续的空闲区。
- 管理员手里有一张**“空闲座位区登记表/链表”**,动态记录着哪些区域是空闲的。
- 核心挑战:
- 分配算法:如果有很多块不连续的空闲区域,该从哪一块里划座位呢?(这是下一节的重点,比如首次适应、最佳适应等)。
- 回收与合并:当一个团体离场后,管理员拆掉隔板。如果他发现这个刚空出来的区域,恰好和旁边的另一个空闲区域是相邻的,他就会把中间的隔板也拆掉,合并成一个更大的连续空闲区。
- 优点:
- 几乎没有内部碎片:因为是按需分配,分配的空间大小和进程需求几乎完全一样,非常节约。
- 缺点:
- 产生外部碎片:这是它的致命弱点。经过多次的分配和回收,整个观众席可能会变成这样:空位(2), 已占(5), 空位(3), 已占(8), 空位(4)... 虽然空位总数很多(2+3+4=9),但此时如果来一个6人的团体,却找不到任何一块连续的空闲区域能容纳他们。这些总和很大但自身太小而无法利用的零散空闲区域,就叫做外部碎片。
- 紧凑技术:为了解决外部碎片,管理员可以发起一次“大挪移”(紧凑):让所有在场的观众都往前坐,把后面的零散空位合并成一个大的连续空位。但这需要所有观众都能灵活地移动座位(进程支持动态重定位),且“大挪移”本身非常耗时。
一句话总结:按需分配,利用率高,但会产生难以利用的“外部碎片”。
内部碎片 vs. 外部碎片:一个形象的区分
- 内部碎片 (Internal Fragmentation):
- 成因:分配单位(如固定分区)大于请求大小。
- 比喻:你买了一整瓶500ml的矿泉水(分配单位),但只喝了300ml(请求大小),瓶子里剩下的200ml水,就是内部碎片。这瓶水已经被你占有了,别人不能喝,但你自己也不喝了。
- 外部碎片 (External Fragmentation):
- 成因:多次分配回收后,产生大量不连续的小空闲块。
- 比喻:你的桌子上堆满了书,书与书之间有很多零散的空隙。把所有空隙加起来,可能能放下一本大字典,但没有任何一个单独的空隙足够大。这些“无法利用的空隙”,就是外部碎片。
分配方式 | 是否有内部碎片 | 是否有外部碎片 |
---|---|---|
单一连续分配 | 有 (可能很大) | 无 |
固定分区分配 | 有 | 无 |
动态分区分配 | 无 (或极小) | 有 |
必会题与详解
题目一:请解释什么是内部碎片和外部碎片,并说明固定分区分配和动态分区分配各会产生哪种碎片,为什么?
答案详解:
定义:
- 内部碎片:指已经分配给进程的内存空间中,进程未使用的部分。它存在于一个已分配区域的“内部”。
- 外部碎片:指内存中那些因为太小而无法分配给任何进程的空闲内存区域。它存在于已分配区域的“外部”。
成因分析:
- 固定分区分配产生内部碎片:因为这种方式预先将内存划分为固定大小的分区。当一个进程需要内存时,系统会分配一个大小大于或等于其需求的分区。如果分区大小严格大于进程需求,那么多出来的这部分空间就属于该进程,但不会被使用,从而形成了内部碎片。它不会产生外部碎片,因为分区大小是固定的,不会有比最小分区还小的空闲块。
- 动态分区分配产生外部碎片:因为这种方式是按进程实际需求大小来分配内存的。经过多次分配和回收后,内存中会留下许多不连续的小块空闲区。这些空闲区单独来看可能都无法满足新进程的需求,但它们加起来的总和可能很大。这些无法被利用的空闲小块就是外部碎片。它几乎不产生内部碎片,因为是按需分配的。
题目二:在动态分区分配中,当回收一个已分配的分区时,为什么要检查其是否与相邻的空闲分区合并?
答案详解:
检查并合并相邻空闲分区是为了减少外部碎片,提高内存利用率。
如果不进行合并,那么每次回收内存时,都只会在内存中增加一个与被回收进程同样大小的小空闲块。随着系统的运行,这将导致内存中充满大量不连续的、细碎的空闲分区。这些小分区很难满足新进程(尤其是较大进程)的分配请求,即使它们的总和很大,也无法被有效利用,这就是外部碎片问题。
通过在回收时主动检查并合并相邻的空闲分区,可以将两个或三个小空闲块合并成一个大的、连续的空闲块。这个大的空闲块能够满足更多进程的分配需求,从而显著地提高了内存的整体利用率,缓解了外部碎片问题。
题目三:什么是“紧凑”(Compaction)技术?它主要用于解决哪种内存分配方式的什么问题?使用该技术需要什么样的硬件支持?
答案详解:
定义:“紧凑”技术是指操作系统通过移动内存中各个进程的位置,将所有分散的空闲分区拼接成一个大的、连续的空闲区的过程。
解决的问题:它主要用于解决动态分区分配方式中产生的外部碎片问题。
需要的硬件支持:使用紧凑技术的一个关键前提是,进程在内存中的物理位置可以被改变。这意味着程序在编译链接时不能使用绝对地址。系统必须采用动态重定位的地址转换方式。这需要硬件支持,即必须有重定位寄存器(基址寄存器)和界地址寄存器(限长寄存器)。当一个进程被移动后,操作系统只需要修改其在重定位寄存器中存放的物理起始地址,程序就可以在新的位置上继续正确运行,而无需修改程序代码中的任何地址。