- 姓名:林永鑫
- 学号:201821121040
- 班级:计算1812
1. 记录内存空间使用情况
定义结构体allocated_block,结构体中指针allocated_block_head指向链表表头,调用alloc_process()函数来为进程分配内存空间时,就将进程块节点添加到链表中。
struct allocated_block { int pid; int size; int start_addr; char process_name[process_name_len]; struct allocated_block *next; }; struct allocated_block *allocated_block_head=NULL;
2. 记录空闲分区
定义结构体free_block_type来存放空闲内存块,结构体中的全局指针变量free_block来指向链表的头结点,调用alloc_process函数来为进程分配内存空间时,就会使用最差适应算法来从空闲分区中选出一块空闲内存分配给进程。
struct free_block_type { int size; int start_addr; struct free_block_type *next; }; struct free_block_type *free_block=NULL;
3. 内存分配算法
使用了最差适应算法(Worst Fit):从全部空闲区中找出能满足作业要求的、且大小最大的空闲分区,从而使链表中的结点大小趋于均匀,适用于请求分配的内存大小范围较窄的系统。为适应此算法,空闲分区表(空闲区链)中的空闲分区按大小从大到小进行排序,自表头开始查找到第一个满足要求的自由分区分配。该算法保留小的空闲区,尽量减少小的碎片产生。
int rearrange_WF() { struct free_block_type *head= free_block; struct free_block_type *forehand,*pre,*rear; int i; if(head== NULL) return -1; for(i= 0;i< free_block_count-1;i++) { forehand= head; pre= forehand->next; rear= pre->next; while(pre->next!= NULL) { if(forehand== head&&forehand->size>= pre->size) { //比较空闲链表中第一个空闲块与第二个空闲块空间的大小 head->next= pre->next; pre->next= head; head= pre; forehand= head->next; pre= forehand->next; rear= pre->next; } else if(pre->size>= rear->size) { //比较链表中其它相邻两个结点的空间的大小 pre->next= rear->next; forehand->next= rear; rear->next= pre; forehand= rear; rear= pre->next; } else { forehand= pre; pre= rear; rear= rear->next; } } } return 0; }
4. 内存释放算法
找到对应的链表节点,释放ab数据结构结点
int dispose(struct allocated_block *free_ab) { struct allocated_block *pre,*ab; if(free_block== NULL) return -1; if(free_ab== allocated_block_head) //如果要释放第一个结点 { allocated_block_head= allocated_block_head->next; free(free_ab); } else { pre= allocated_block_head; ab= allocated_block_head->next; //找到free_ab while(ab!= free_ab) { pre= ab; ab= ab->next; } pre->next= ab->next; free(ab); } return 1; }
将ab所表示的已分配区归还,并进行可能的合并
int free_mem(struct allocated_block *ab) { int algorithm= ma_algorithm; struct free_block_type *fbt,*pre,*work; fbt= (struct free_block_type*)malloc(sizeof(struct free_block_type)); if(!fbt) return -1; pre= free_block; fbt->start_addr= ab->start_addr; fbt->size= ab->size; fbt->next= NULL; if(pre!= NULL) { while(pre->next!= NULL) pre= pre->next; pre->next= fbt; } else { free_block= fbt; } rearrange_FF(); pre= free_block; work= pre->next; while(work!= NULL) { if(pre->start_addr+ pre->size== work->start_addr) { pre->size+= work->size; free(work); work= pre->next; } else { pre= work; work= work->next; } } current_free_mem_size+= ab->size; return 1; }
将ab所表示的已分配区归还,并进行可能的合并
void kill_process() { struct allocated_block *ab; int pid; printf("Kill Process,pid="); scanf("%d",&pid); getchar(); ab= find_process(pid); if(ab!= NULL) { free_mem(ab); //释放ab所表示的分配区 dispose(ab); //释放ab数据结构结点 } }
删除进程,归还分配的存储空间,并删除描述该进程内存分配的结点
5. 运行结果
(1)产生测试数据
int main(int argc, char const *argv[]){
free_block = init_free_block(mem_size); //初始化空闲区
set_mem_size();
int size;
srand((unsigned)time(0));
//初始化三个进程
for(int i=0;i<3;i++){
size=rand()%100;
new_process();
}
//分配、释放内存10次
int m=0;
int n=0;
while(m<10){
n=m+1;
//结束一个进程
kill_process()
size=rand()%100;
//创造一个进程
new_process(size);
display_mem_usage();
m++;
}
}
(2)解释结果
第一组:为进程process-02分配了从0开始,大小为89的内存单元,分配后空闲分区内存剩余地址为从89开始,大小为935的空间。
第二组:为进程process-01分配了从89开始,大小为35的内存单元,分配后空闲分区内存剩余地址为从124开始,大小为900的空间。
第三组:为进程process-03分配了从124开始,大小为55的内存单元,分配后空闲分区内存剩余地址为从179开始,大小为845的空间。
第四组:释放了进程process-03从124开始,大小为55的内存单元,释放后空闲分区内存剩余地址为从124开始,大小为900的空间。