一、首次适应算法(First Fit)
算法描述:
以空闲分区为例,FF算法要求空闲分区链以地址递增的次序链接,在分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止。然后再按作业的大小,从该分区中划出一块内存空间,分配给请求者,余下的空闲分区仍留在空闲链中,若从链首直至链尾都不能找到一个能满足要求的分区,则表明系统已没有足够大的内存分配给该进程,内存分配失败,返回。
该算法倾向于优先利用内存中的低址部分的空闲分区,从而保留了高址部分的大空闲分区,这为以后到达的大作业分配大的内存空间创造了条件。其缺点是低值部分不断被划分,会留下许多难以利用的,很小的空闲分区,称为碎片。而每次查找又都是从低址部分开始的,这无疑又会增加查找可用空闲分区的开销。
算法实现:
/*
*模拟首次适应算法
*/
#include<stdio.h>
#include<malloc.h>
typedef struct node //定义空闲分区
{
int head_addr , tail_addr ; //定义当前分区的起始地址
int memory_size ; //分区大小
struct node *next ; //指向下一个空闲分区的指针
} MemoryNode ;
typedef struct //定义空闲分区链表的数据结构
{
MemoryNode *head , *tail ; //指向分区链表的头尾指针
} PartitionTable ;
/*
*初始化系统当前分区
*/
bool init_memory(PartitionTable *pt) ;
/*
*进行当前分区链表的扫描操作
*/
void scan_memory(PartitionTable *pt) ;
/*
*内存空间的分配函数,首次适应算法
*/
bool first_in(PartitionTable *pt , int memory) ;
/*
*测试主函数
*/
int main()
{
PartitionTable *pt ;
int memory ;
pt = (PartitionTable*)malloc(sizeof(PartitionTable)) ;
if(pt == NULL)
{
printf("The memory is not enough ! \n") ;
exit(0) ;
}
pt->head = NULL ;
pt->tail = NULL ;
if(! init_memory(pt))
{
printf("The memory deliever failed ! \n") ;
exit(0) ;
}
scan_memory(pt) ;
while(true)
{
printf("Please input the memory request : ") ;
scanf("%d" , &memory) ;
if(first_in(pt , memory))
{
printf("The memory deliever success ! \n") ;
}
else
{
printf("The memory deliever failed ! \n") ;
}
scan_memory(pt) ;
}
return 0 ;
}
/*
*初始化当前分区链表
*对内存空间进行连续分配
*/
bool init_memory(PartitionTable *pt)
{
//分配十个大小相等的空闲分区
int memory_num = 10 ;
MemoryNode *node ;
for(int i = 0 ; i < memory_num ; i++)
{
node = (MemoryNode*)malloc(sizeof(MemoryNode)) ;
if(node == NULL)
{
printf("The memory is not enough ! \n") ;
return false ;
}
node->head_addr = i * 100 ;
node->tail_addr = (i + 1) * 100 - 1 ;
node->memory_size = 100 ;
node->next = NULL ;
if(pt->head == NULL)
{
pt->head = pt->tail = node ;
}
else
{
pt->tail->next = node ;
pt->tail = node ;
}
}
return true ;
}
/*
*进行当前分区的扫描操作
*/
void scan_memory(PartitionTable *pt)
{
if(pt == NULL || pt->head == NULL)
{
printf("The PartitionTable is NULL ! \n") ;
return ;
}
MemoryNode *node ;
node = pt->head ;
printf("------分区链表---------- \n") ;
printf("head_address tail_address memory_size\n") ;
while(node)
{
printf(" %4d %4d %4d \n" , node->head_addr , node->tail_addr , node->memory_size) ;
node = node->next ;
}
}
/*
*首次适应算法
*/
bool first_in(PartitionTable *pt , int memory)
{
MemoryNode *memoryNode , *preNode = NULL ;
memoryNode = pt->head ;
while(memoryNode)
{
if(memoryNode->memory_size > memory)
{
MemoryNode *node ;
node = (MemoryNode*)malloc(sizeof(MemoryNode)) ;
if(node == NULL)
{
printf("The memory resource is not enough ! \n") ;
return false ;
}
//分配新的碎片节点
node->head_addr = memoryNode->head_addr + memory ;
node->tail_addr = memoryNode->tail_addr ;
node->memory_size = memoryNode->memory_size - memory ;
if(preNode != NULL)
{
preNode->next = node ;
}
else
{
pt->head = node ;
}
if(memoryNode == pt->tail)
{
pt->tail = node ;
}
node->next = memoryNode->next ;
delete memoryNode ; //清除内存空间
return true ;
}
if(memoryNode->memory_size == memory)
{
if(memoryNode == pt->head && memoryNode == pt->tail)
{
pt->head = pt->tail = NULL ;
}
else if(memoryNode == pt->head)
{
pt->head = memoryNode->next ;
}
else if(memoryNode == pt->tail)
{
pt->tail = preNode ;
}
else
{
preNode->next = memoryNode->next ;
}
delete memoryNode ;
return true ;
}
preNode = memoryNode ; //记录当前节点的前驱指针
memoryNode = memoryNode->next ;
}
return false ;
}
二、最佳适应算法(Best Fit)
算法描述:
所谓“最佳”是指,每次为作业分配内存时,总是能满足要求、又是最小的空闲分区分配给作业,避免“大材小用”。为了加速寻找,该算法要求将所有的空闲分区按其容量以从小到大的顺序形成一空闲分区链。这样,第一次找到的能满足要求的空闲分区必然是最佳的。孤立的看,最佳适应算法似乎是最佳的,然而在宏观上却不一定。因为每次分配后所切割下来的剩余部分总是最小的,这样,在存储器中会留下许多难以利用的碎片。
算法实现:
/*
*模拟最佳适应算法
*/
#include<stdio.h>
#include<malloc.h>
typedef struct node //定义空闲分区
{
int head_addr , tail_addr ; //定义当前分区的起始地址
int memory_size ; //分区大小
struct node *next ; //指向下一个空闲分区的指针
} MemoryNode ;
typedef struct //定义空闲分区链表的数据结构
{
MemoryNode *head , *tail ; //指向分区链表的头尾指针
} PartitionTable ;
/*
*初始化系统当前分区
*/
bool init_memory(PartitionTable *pt) ;
/*
*进行当前分区链表的扫描操作
*/
void scan_memory(PartitionTable *pt) ;
/*
*内存空间的分配函数,首次适应算法
*/
bool best_fit(PartitionTable *pt , int memory) ;
/*
*进行分区链表的排序操作,方便起见选择冒泡
*/
void sort_mao(PartitionTable *pt) ;
/*
*进行分区节点的插入
*/
bool insert_table(PartitionTable *pt , MemoryNode *node) ;
/*
*进行两个节点的交换操作
*只是进行内容的交换
*/
void swap_x(MemoryNode *m1 , MemoryNode *m2) ;
/*
*测试主函数
*/
int main()
{
PartitionTable *pt ;
int memory ;
pt = (PartitionTable*)malloc(sizeof(PartitionTable)) ;
if(pt == NULL)
{
printf("The memory is not enough ! \n") ;
exit(0) ;
}
pt->head = NULL ;
pt->tail = NULL ;
if(! init_memory(pt))
{
printf("The memory deliever failed ! \n") ;
exit(0) ;
}
scan_memory(pt) ;
while(true)
{
printf("Please input the memory request : ") ;
scanf("%d" , &memory) ;
if(best_fit(pt , memory))
{
printf("The memory deliever success ! \n") ;
}
else
{
printf("The memory deliever failed ! \n") ;
}
scan_memory(pt) ;
}
return 0 ;
}
/*
*初始化当前分区链表
*对内存空间进行连续分配
*/
bool init_memory(PartitionTable *pt)
{
//分配十个大小相等的空闲分区
int memory_num = 10 ;
MemoryNode *node ;
for(int i = 0 ; i < memory_num ; i++)
{
node = (MemoryNode*)malloc(sizeof(MemoryNode)) ;
if(node == NULL)
{
printf("The memory is not enough ! \n") ;
return false ;
}
node->head_addr = i * 100 ;
node->tail_addr = (i + 1) * 100 - 1 ;
node->memory_size = 100 ;
node->next = NULL ;
if(pt->head == NULL)
{
pt->head = pt->tail = node ;
}
else
{
pt->tail->next = node ;
pt->tail = node ;
}
}
return true ;
}
/*
*进行当前分区的扫描操作
*/
void scan_memory(PartitionTable *pt)
{
if(pt == NULL || pt->head == NULL)
{
printf("The PartitionTable is NULL ! \n") ;
return ;
}
MemoryNode *node ;
node = pt->head ;
printf("------分区链表---------- \n") ;
printf("head_address tail_address memory_size\n") ;
while(node)
{
printf(" %4d %4d %4d \n" , node->head_addr , node->tail_addr , node->memory_size) ;
node = node->next ;
}
}
/*
*首次适应算法
*/
bool best_fit(PartitionTable *pt , int memory)
{
MemoryNode *memoryNode , *preNode = NULL ;
memoryNode = pt->head ;
MemoryNode *node ;
while(memoryNode)
{
if(memoryNode->memory_size > memory)
{
node = (MemoryNode*)malloc(sizeof(MemoryNode)) ;
if(node == NULL)
{
printf("The memory resource is not enough ! \n") ;
return false ;
}
//分配新的碎片节点
node->head_addr = memoryNode->head_addr + memory ;
node->tail_addr = memoryNode->tail_addr ;
node->memory_size = memoryNode->memory_size - memory ;
if(memoryNode == pt->head && memoryNode == pt->tail)
{
pt->head = pt->tail = NULL ;
}
else if(memoryNode == pt->head)
{
pt->head = memoryNode->next ;
}
else if(memoryNode == pt->tail)
{
pt->tail = preNode ;
}
else
{
preNode->next = memoryNode->next ;
}
delete memoryNode ; //清除内存空间
insert_table(pt , node) ;
return true ;
}
if(memoryNode->memory_size == memory)
{
if(memoryNode == pt->head && memoryNode == pt->tail)
{
pt->head = pt->tail = NULL ;
}
else if(memoryNode == pt->head)
{
pt->head = memoryNode->next ;
}
else if(memoryNode == pt->tail)
{
pt->tail = preNode ;
}
else
{
preNode->next = memoryNode->next ;
}
delete memoryNode ;
return true ;
}
preNode = memoryNode ; //记录当前节点的前驱指针
memoryNode = memoryNode->next ;
}
return false ;
}
/*
*进行两个节点的交换操作
*只是进行内容的交换
*/
void swap_x(MemoryNode *m1 , MemoryNode *m2)
{
int temp ;
temp = m1->head_addr ;
m1->head_addr = m2->head_addr ;
m2->head_addr = temp ;
temp = m1->tail_addr ;
m1->tail_addr = m2->tail_addr ;
m2->tail_addr = temp ;
temp = m1->memory_size ;
m1->memory_size = m2->memory_size ;
m2->memory_size = temp ;
}
/*
*进行分区链表的排序
*/
void sort_sort(PartitionTable *pt)
{
MemoryNode *n1 , *n2 ;
n1 = n2 = NULL ;
for(n1 = pt->head ; n1 ; n1 = n1->next)
{
for(n2 = n1->next ; n2 ; n2 = n2->next)
{
if(n1->memory_size > n2->memory_size)
{
swap_x(n1 , n2) ;
}
}
}
}
/*
*进行分区节点的插入
*/
bool insert_table(PartitionTable *pt , MemoryNode *node)
{
printf("The node is %d %d %d \n" , node->head_addr , node->tail_addr , node->memory_size) ;
if(pt->head == NULL)
{
pt->head = pt->tail = node ;
return true ;
}
MemoryNode *n , *preNode = NULL ;
n = pt->head ;
while(n)
{
if(n->memory_size > node->memory_size)
{
if(n == pt->head)
{
node->next = n ;
pt->head = node ;
}
else
{
preNode->next = node ;
node->next = n ;
}
return true ;
}
preNode = n ;
n = n->next ;
}
pt->tail->next = node ;
pt->tail = node ;
return true ;
}