“无规矩不成方圆”,在计算机中,操作系统需要对所有的软硬件资源进行管理。对于内存的使用情况操作系统也必须进行跟踪,以便于管理内存。跟踪内存使用情况的两种方法:位图和空闲区链表
使用位图跟踪内存,内存会被划分成大小合适的单元。一个单元的使用情况对应着位图中的一位,使用"0"或者“1”表示这个单元正在被使用,另一个也就表示这个单元现在是空闲的。
另外一种跟踪内存的办法就是使用一个链表,链表的结点包含:
内存的起始地址和长度间接地描述了这部分内存区域。
假设这个链表是按照物理内存地址的顺序来排序的。如果有一块使用内存空间被释放,那么与它相关联的链表的结点就需要更新,将P替换成H,替换后如果相邻结点的指示标志相同(都是P/H),那么可以合并成一个,更新结点的成员,链表就少了一个结点。
按照链表存储管理的方法,假设这个跟踪内存的链表按照物理内存地址的顺序存储进程和空闲区,并且存储管理器知道要给进程分配多少物理内存。
有以下几种分配内存的算法
首次适配算法
思想:对链表进行顺序搜索,如果找到了一块可以分割出预期内存大小的空闲区,则将这块内存区分割预期的内存大小给进程,如果还剩下有,则剩下的部分形成一个新的空闲区。
优点:速度快,直接找到第一块合适的空闲区就可以,找到了不需要继续搜索下去。
缺点:每一次分配,都需要从头搜索链表,效率不高。
下次适配算法
思想:每次找到一块合适的空闲区(可以分割出预期内存大小的空闲区),记录当前的位置,下次就可以在上次结束的地方开始搜索。
优点:不需要每次从头开始搜索合适的空闲区。
缺点:我自己认为这个算法并不是特别地好,因此下次要分配的内存大小很可能比上次的要小,如果采用这个算法,在记录的位置前面可能有许多合适的空闲区被忽略了!
最佳适配算法
思想:二话不说,先搜索一遍链表,找到最合适的空闲区,这里的“最合适”指的是这块空闲区分配后形成的新空闲区相对来说最小。
优点:优点我说不上来,以后来填补空缺吧。
缺点:虽然被称为“最佳适配”,但实际上并不是最佳的。第一,效率太慢了,二话不说就先把链表搜索一遍。第二,会形成很多小的新空闲区,这些很小的空闲区利用率太低了,造成了内存浪费。
最差适配算法
思想:和最佳适配算法的思路相反,先搜索整个链表,找到“最不合适”,也就是这块空闲区分配后形成的新空闲区相对来说最大。
优点:对比最佳适配算法,最差适配算法就不容易产生很多小的新空闲区,新空闲区比较大,可以继续使用的概率大。
缺点:搜索整个链表,效率相对较低。
另外需要讨论的一种内存分配算法是快速适配算法
在此之前,用到的内存分配算法只维护关联有进程和空闲区的单链表。实际上在分配的时候,只关心空闲区,所以可以为进程和空闲区维护各自的链表。这样就可以提高算法的整体效率。
思想:维护一个n项的表,表的每一项都是指针,指向空闲区链表表头的指针。例如,第一项指向大小为0-4KB的空闲区链表的头结点,第二项指向大小为5-8KB的空闲区链表的头结点。
优点:可以快速找到所需大小的空闲区
缺点:需要做大量增删查改操作。当一个被占用的内存转变为空闲区,寻找它的相邻块并判断是否可以合并比较耗时,如果不合并会形成很多利用率低下的小的新空闲区。