分区存储管理是把主存储器中的用户区做为一个连续区或分红若干个连续区进行管理,每一个连续区中可装入一个做业。算法
多道程序系统通常都采用多个分区的存储管理,具体可分为固定分区和可变分区两种方式。数据结构
把主存中可分配的用户区域预先划分红若干个连续的分区,每一个连续区的大小能够相同,也能够不一样。可是,一旦划分好分区以后,主存中分区的个数就固定了,且每一个分区的大小也固定不变。这是一种静态分区法。性能
在固定分区方式管理下,每一个分区用来装入一个做业。因为主存中有多个分区,就可同时在每一个分区中装入一个做业。因此,这种存储管理方式适用于多道程序系统。 spa
为了管理主存空间的使用,必须设置一张“主存分配表”(分区说明表),以说明各分区的分配状况。主存分配表中应指出各分区的起始地址和长度,并为每一个分区设一个标志位。当标志位为“0”时,表示对应的分区是空闲分区,当标志位为非“0”时,表示对应的分区已被某做业占用。空闲分区能够用来装做业。3d
看成业队列中有做业要装入主存时,存储管理可采用“顺序分配算法”进行主存空间的分配。
顺序查看主存分配表,找到一个标志为“0”的而且长度大于或等于欲装入做业的地址空间长度的分区,则把此分区分配给该做业,相应表目的标志位改为做业名的标识;若找不到一个这样的空闲分区,则该做业暂时不能装入主存。 blog
主存空间的释放很简单。某做业执行结束后必须归还所占的分区,这时存储管理根据做业名查看主存分配表,找到相应的表目后,把其中的标志位从新置成“0”便可。 排序
固定分区管理方式下做业的地址转换常采用静态重定位技术。 递归
固定分区管理方式下只考虑判断其物理地址便可。常采用“界限寄存器对”法。
If 下限地址<=物理地址<=上限地址队列
Then 继续
Else 产生“越界中断” ,转越界中断的处理子程序 进程
采用覆盖技术
优势:实现简单,无外部碎片
缺点:
a.当用户程序太大时,可能全部的分区都不能知足需求,此时不得不采用覆盖技术解决,但这又会下降性能
b.会产生内部碎片,碎片大,存在小分区占用大做业的状况,内存利用率低。
解决办法:采用可变分区存储管理
内存管理的可变分区模式,又称变长分区模式、动态分区分配模式。这种分配方式不会预先划份内存分区,而是在进程装入内存时,根据进程的大小动态地创建分区,并使分区的大小正好适合进程的须要。所以系统分区的大小和数目是可变的。
与固定分区的区别就是:动态的划分分区。
克服固定分区管理的“内碎片”问题。
1.可变分区模式下,刚开始,OS就绪,但任何用户程序未进入内存前整个用户内存区是一大空间。已占用区和空闲分区并非绝对的。
2.必须有表来记录分区的状况。
3.程序进入内存时的例行工做就是分配空闲区和装入程序,并修改相应的空闲表和已分配区表。
4.一旦一个内存分区被分配给一个进程,该进程能够被装入该块中执行,装入时需重定位。
系统要使用什么样的数据结构来记录内存的使用状况?
可变分区分配算法
把一个新做业装入内存时,须要按照必定的可变分区分配算法,从空闲分区表(或空闲分区链)中选出一个分区分配给该做业。
在可变分区分配方式中,当有不少空闲分区都知足需求时,应该使用哪一个分区进行分配?
这里介绍三种可变分区分配算法
算法思想:每次都从低地址开始查找,找到第一个能知足大小的空闲分区。
实现步骤:
空闲区地址由低到高排序
=>1.顺序查找各个空闲区,把第一个找到能容纳申请要求的内存区分配给申请者.(若空闲区比做业长度大,则分割该空闲区。一部分分配给做业一部分空闲。)
=>2.调整相应的空闲分区表和已分配分区表。
评价:性能通常但实现比较简单直接,易于释放时合并相邻空间分区。比较容易的知足大做业的须要。完成一次分配平均须要的搜索次数较大,影响了工做效率。
尽量地利用存储器中低地址的空闲区,而尽可能保存高地址的空闲区。
算法思想:因为可变分区分配是一种连续分配方式,为各进程分配的空间必须是连续的一整片区域。所以为了保证当“大进程”到来时能有连续的大片空间,优先使用更小的空闲区。
实现步骤:
空闲分区按容量递增次序连接。每次分配内存时顺序查找空闲分区表,找到大小可以知足要求的第一个空闲分区。
评价:尽量地保留了较大的空间。 产生大量的不能被使用的很小的空闲区。所以这种方法会产生不少的外部碎片。因此该算法分配效果不必定是最佳的。
尽量地利用存储器中小的空闲区,而尽可能保存大的空闲区。
算法思想:为了解决最佳适应算法的问题——即留下太多难以利用的小碎片,能够在每次分配时,优先使用最大的连续空闲区,这样分配后的空闲区就不会过小,更方便使用。
实现步骤:
空闲分区按照容量递减次序连接。每次分配内存时顺序查找空闲分区表,找到大小能知足要求的第一个空闲分区。
评价:分割后产生的空闲区通常仍能够供之后分配使用。工做一段时间后,不能知足大做业对空闲区的请求。
尽量地利用存储器中大的空闲区。
三种算法的比较:
只比固定分区管理增长了合并相邻空闲区的操做。
主要是为了及时减小“外碎片”,利于从此大做业的到来。
实现回收内存空间,关键是修改空闲分区表和已分配分区表。
回收内存分区时可能会遇到的四种状况:
(a)若释放区R既有上邻空闲区,又有下邻空闲区。将三个空闲区合并成一个大空闲区。
先将R与F2合并记为F2,
再将F2与F1合并记为F1,并将F2从链中删除。
IF (B+H1=C) AND (C+L2=D)
THEN 修改空闲表,分配表。
(b)若释放区R只有上邻空闲区F1。
则只修改空闲区F1大小便可。
IF (D+H2=E)
THEN 修改空闲表,分配表。
(c)只有下邻空闲区
修改空闲区F2的首地址。
F2的大小=F2的大小+R的大小
(d)既无上邻又无下邻空闲区
Else 修改释放区的首地址为空闲区的起始地址
动态重定位
If 下限地址<=物理地址<=上限地址
Then 继续
Else 产生“越界中断” ,转越界中断的处理子程序
消除了固定分区管理形成的“内碎片”,可是不可避免的在内存空间形成“外碎片”。
采用移动(紧缩)技术。定时的或在内存紧张时,将内存中全部做业移到内存的一端,使其相邻。
通过紧缩后的进程在内存中的位置发生了变化,若不对程序和数据的地址进行修改,在进程就没法运行。
要使其运行,必须进行“动态重定位”
注意:
=》紧缩的时机:
(1)一旦有归还的分区便进行紧缩,系统开销大。
(2)分配算法发现各空闲区不够用,但其和够用时。此法紧缩开销小,更实用。所以,实际的可变分区分配算法比固定分区分配算法主要增长了“紧缩”操做
伙伴系统可看做固定分区分配和可变分区分配的一种折中方案。
采用伙伴系统时,内存是以2的幂次个字节大小的空闲块为分配单位的。系统初启时,只有1个最大的2的幂次的空闲块,它就是整个可用的内存空间。当1个进程申请内存时,系统就分给它1个大于或等于进程所申请尺寸的最小的2的幂次的空闲块。
例如,某进程提出的50KB的内存请求,将首先被系统向上取整,转化为对1个64KB的空闲块的请求。若是此时不存在如此大小的空闲块,则此时可得到的1个最小的比该空闲块大的空闲块将被对分红2个“伙伴”单位。对其中1个伙伴单位的对分过程可能还要继续下去,直到得到1个64KB的空闲块为止。
伙伴系统的内存释放算法考虑将两个伙伴单位合并成1个大1倍的空闲单位。且这个合并过程会递归下去,直到不能继续合并为止。
注意观察下图,合并后的空闲区块也必须是2的幂次个字节
为了实现伙伴系统,系统要为每一种可能的空闲块维护1个空闲块链表。设系统管理的可用内存空间共为2N个字节,则1个伙伴系统最多须要维护N个空闲块链表。因为每种尺寸的空闲块都有一个空闲块队列,所以内存的分配与释放能够有效地进行。
伙伴系统的最大缺陷是不能有效地利用内存,特别是内碎片严重。例如,1个257KB的进程须要占用1个512KB的分配单位,其中将产生255KB的内碎片。另外,每次释放内存时都尽量地合并伙伴单位的作法也会下降系统性能,由于刚合并好的块可能立刻又要对分。一种改进的作法是延迟合并的时机。现在Linux用它。