这篇文章为大家讲解的是操作系统当中内存分配方式——连续分配管理方式,连续分配方式是指一个由用户程序分配一个连续的内存空间,就比如说用户需要一块100MB的内存空间,那么就在内存当中为用户分配一块连续的并且大小为100MB的内存空间,连续分配管理方式主要由单一连续分配、固定分区分配和动态分区分配三种方式。
内存在此分配方式下分为系统区和用户区,系统区仅仅提供操作系统使用,通常在低地址部分,在用户内存当中仅有一道用户程序,也就是说整个内存的用户空间由该程序独占。
这种分配方式的优点是操作简单,并且没有外部碎片,不需要进行内存保护,因为用户当中只有一道程序,不用担心会有第二道程序来干扰这道程序,但是他还有缺点就是只适用于单用户、单任务的操作系统,他有内部碎片而且存储器的利用率极低。
在这里着重说明一下关于内部碎片和外部碎片的问题,内部碎片是指操作系统分配给程序一块内存,但是这个程序并没有将整个内存块占满,也就是在操作系统给他分配的一块内存当中是有剩余空间的,这种碎片就叫做内部碎片。
那么外部碎片就是指操作系统为多个程序分配了多块空间,但是分配以后内存的剩余空间已经很小了,虽然还有剩余但是已经不足以在位其他的程序分配了,所以内部碎片是存在于已经分配的内存区当中,而外部碎片是还没有分配的内存空间。
固定分区分配是一种最简单的多道程序存储管理方式,它可以将用户的内存空间划分成为多块大小相同的区域,每个分区只装入一道作业,当有空闲分区时,便可再从外存的后备队列中选择合适大小的作业装入内存中,如此循环,在划分区域的时候有两种不同的方法。
为便于内存分配,通常将分区按大小排队,并且还要建立一张分区说明表,其中表项包括每个分区的起始地址、大小及状态,当有用户程序需要装入的时候,便检索分区说明表以找到合适的分区分配给程序,如果找到以后并且分配,将分配表中的状态一栏设置为已分配,未找到合适的分区时,则拒绝为该程序分配。
分区号 | 大小/KB | 起址/KB | 状态 |
1 | 12 | 20 | 已分配 |
2 | 32 | 32 | 已分配 |
3 | 64 | 64 | 未分配 |
4 | 128 | 128 | 未分配 |
这样的方式有两个问题,一是程序可能太大而放不进任何一个分区,这个时候就需要采用覆盖技术来使用内存空间;二是当程序小于固定分区大小时,也要占用一个完整的分区,这样的分区就会产生内部碎片,造成内部的空间浪费,固定分区是可用于多道程序设计的最简单的存储分配,不存在外部碎片,但是无法实现多进程共享一个主存区,所以存储空间利用率极其低 。
在固定分区分配中,为了便于分配,建立一张分区使用说明表,通常按分区大小排队,各表项包括每个分区的起始地址、大小状态,分配内存的时候检索分区使用说明表。找到一个能够满足要求的并且尚未分配的分区分配给装入程序,并且将对应的程序的状态设置为“已分配”;若是找不到这样的分区,则拒绝分配。回收内存的时候在将对应的表项的状态设置为“未分配”即可。
这样的分配方式又称为可变分区分配,它时在进程装入内存的时候,根据进程的需要,动态地为之分配内存,并使分区的大小正好适合进程的需要,因此,系统中分区的大小和数目时可变的。
内存空间首先要分配一部分给操作系统,比如说操作系统的内核就是常驻内存的,其余部分就是分配给用户的,开始先装入一部分的进程以后,由于内存空间有限,操作系统会根据请求不断的将内存中的进程换出,外存中的程序换入,如此循环往复。
动态分区在最开始分配的时候是很好的,随着时间的推移,内存中产生越来越多的小的内存块,内存的利用率也会随之下降,这些小的内存块被称为外部碎片,没有分配个某一个进程,但是剩余的内存空间有不足以分配给其他进程,所以也就产生了外部碎片。它存在于所有分区的外部,这与固定分区的内部碎片正好相对应,克服外部碎片可以通过紧凑技术来解决,这是一种对内存碎片的整理程序,在这里不做过的赘述。
在进程装入或换入主存的时候,若内存中有着足够大的空闲块,则操作系统必须确定分配哪个进程块给进程使用,这就是动态分区的分配策略,考虑以下几种算法。
首次适应算法最简单,通常也是最好的和最快的,不过首次适应算法会使得内存的低地址部分出现很小的空闲区,但是每次分配查找的时候都必须要经过这些区,其实也无形当中增加了系统的开销。
邻近适应算法试图解决这个问题,但他常常导致在内存的尾部分裂成许多小碎片,通常比首次适应算法要差。因为上一次分配后的空间,可能因为进程的结束而被释放,这个时候也是空闲状态,但是系统对他进行一次分配以后,即便他再次处于空闲状态,他也不会再次参与分配了。
最佳适应算法虽然被称为是最佳,但是他的性能通常很差,因为每次分配会留下很小的难以利用的内存块,会产生最多的外部碎片。毕竟总有一些小的内存块无法满足要求。
最坏适应算法与最佳适应算法正好相反,他选择最大的内存块,但是却把最大的连续内存划分开,会很快的导致没有大的内存块可以使用,因此性能也很差。
在动态分区分配中,与固定分区分配相类似,设置一张空闲分区链,并且按照起始地址排序,分配内存的时候,检索空闲分区链,找到所需要的分区,若其大小大于请求大小,便从该分区当中按照请求的大小分割一块空间分配给装入进程,若剩余部分小到不足以划分,则无须分割。
以上三种分配方式有一个共同的特点就是,用户程序在内存当中都是连续存放的,在连续存放的方式当中,即使内存由超过1GB的内存,可是却未必有超过1GB的连续内存,需要1GB内存的作业仍然是无法运行的,所以就引入了分连续分配的内存管理方式,他的存储密度是低于连续分配的管理方式的。
非连续分配方式有根据分区的大小是否固定,分为页式存储管理和段式存储管理,而在页式存储管理当中又将作业运行是否需要将全部的页面都调入内存分为基本分页式存储管理和请求分页式存储管理。