操作系统第5次实验报告:内存管理
2020-05-17 11:47 Wangpj 阅读(288) 评论(0) 编辑 收藏 举报姓名:王丕杰
班级:计算1812
学号:201821121052
1. 记录内存空间使用情况
定义已分配分区的结构体allocated_block,定义一个指针allocated_block_head指向链表表头。
/*记录内存空间使用情况*/ typedef struct allocated_block{ int pid; int size; int start_addr; char process_name[PNAME_LEN]; struct allocated_block *next; }AB;
AB *allocated_block_head = NULL; /*进程分配内存块链表的首指针*/
2. 记录空闲分区
定义空闲分区的结构体free_block_type,定义一个指针free block指向链表表头。
/*记录空闲分区*/ typedef struct free_block_type{ int size; int start_addr; struct free_block_type *next; }FBT; FBT *free_block; /*指向内存中空闲块链表的首指针*/
3. 内存分配算法
(1)内存分配算法:首次适配算法
(2)首次适应算法从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。
(3)代码如下:
void Do_Allocate_Mem(AB *ab){ //分配内存 int request = ab->size; FBT *tmp = free_block; while(tmp != NULL){ if(tmp->size >= request){ ab->start_addr = tmp->start_addr; int residue = tmp->size - request; tmp->size = residue; tmp->start_addr = tmp->start_addr + request; return ; } tmp = tmp->next; } } int Allocate_Mem(AB *ab){ //分配内存应用 FBT *fbt,*pre; int request_size=ab->size; fbt = pre = free_block; int f = Find_Free_Mem(request_size); //寻找可分配 if(f == -1){ //空闲内存不足 printf("Not enough free memory!\n"); return -1; }else{ if(f == 0){ //内存紧缩后分配 Memory_Compact(); } Do_Allocate_Mem(ab); //分配 } Rearrange(ma_algorithm); //重排空闲分区 return 1; } int Alloc_Process(PRO prc){ //为进程分配内存 AB *ab; int ret; ab = (AB*)malloc(sizeof(AB)); if(!ab) exit(-5); ab->next=NULL; pid++; strcpy(ab->process_name,prc.process_name); ab->pid = pid; ab->size=prc.size+rand()%ALLOC_SIZE; //随机分配内存 ret = Allocate_Mem(ab); //分配内存,ret==1表示分配成功 if((ret == 1) && (allocated_block_head == NULL)){ //若allocated_block_head尚未赋值 allocated_block_head = ab; return 1; }else if(ret == 1){ //分配成功 ab->next = allocated_block_head; allocated_block_head = ab; return 2; }else if(ret == -1){ //分配不成功 printf("Fail!\n"); free(ab); return -1; } return 3; }
4. 内存释放算法
(1)内存释放:找到对应的链表节点,释放释放杀死进程的内存块,归还进程的已分配的存储空间,按大小从小到大排序,销毁杀死进程的结点。
(2)代码如下:
int Dispose(AB *free_ab){ //释放链表ab节点 AB *pre,*ab; if(free_ab == allocated_block_head){ //若释放首节点 allocated_block_head = allocated_block_head->next; free(free_ab); return 1; } pre = allocated_block_head; //否则 ab = allocated_block_head->next; while(ab!=free_ab){ pre = ab; ab = ab->next; } pre->next = ab->next; free(ab); return 2; } int Free_Mem(AB *ab){ //更新分区表归还已分配区,以及可能的合并 int algorithm = ma_algorithm; FBT *fbt,*pre,*work; fbt = (FBT*)malloc(sizeof(FBT)); if(!fbt) return -1; fbt->size = ab->size; fbt->start_addr = ab->start_addr; //插入链尾 work = free_block; if(work == NULL){ free_block = fbt; fbt->next == NULL; }else{ while(work ->next != NULL){ work = work->next; } fbt->next = work->next; work->next = fbt; } Rearrange_FIR(); //首次适配算法 pre = free_block; while(pre->next){ work = pre->next; if(pre->start_addr + pre->size == work->start_addr ){ pre->size = pre->size + work->size; pre->next = work->next; free(work); continue; }else{ pre = pre->next; } } Rearrange(ma_algorithm); //按照当前算法排序 return 1; } int Kill_Process(int pid){ //释放进程内存 AB *ab; ab = Find_Process(pid); if(ab!=NULL){ Free_Mem(ab); //释放分配表 Dispose(ab); //释放节点 return 0; }else{ return -1; } }
5. 运行结果
(1)产生测试数据
随机为3个进程分配、释放内存10次以上,即随机产生10组以上数据:
#define PROCESS_NUM 3 //进程数 int main(int argc, char const *argv[]){ int sel1,sel2; int total=0; //记录分配内存的次数 free_block=Init_Free_Block(mem_size); //初始化空闲区 PRO prc[PROCESS_NUM]; //存放要加载的进程 Init_Program(prc,PROCESS_NUM); //对这几个程进程进行初始化 srand((unsigned)time(NULL)); for(int i=0;i<DATA_NUM;++i) { sel1=rand()%2; int count=0; //统计三个进程中有多少个进程已经分配内存 for(int j=0;j<PROCESS_NUM;++j){ if(prc[j].pid!=-1) count++; } //如果全部分配进程或者进程分配到达10次,那么就不能继续分配内存 if((count==PROCESS_NUM && sel1==0)||total==10) sel1=1; //如果全部未分配进程,那么就不能继续释放内存 if(count==0 && sel1==1) sel1=0; if(sel1==0) //为进程分配内存 { //随机找到一个未分配内存的进程 do{ sel2=rand()%PROCESS_NUM; }while(prc[sel2].pid!=-1); Alloc_Process(prc[sel2]); //分配内存空间 prc[sel2].pid=pid; //改变标记 total++; Display_Mem_Usage(); //显示结果 } else //释放进程占用的内存空间 { do{ //随机找到一个可释放进程 sel2=rand()%PROCESS_NUM; }while(prc[sel2].pid==-1); Kill_Process(prc[sel2].pid);//释放内存空间 prc[sel2].pid=-1; //改变标记 Display_Mem_Usage(); //显示 } }
(2)解释结果
①第一次内存分配:进程名为process-01,起始地址为0,进程占用内存大小为21;剩余空闲分区首地址为21,大小为1003;随后释放进程process-01。
②第二次内存分配:进程名为process-01,起始地址为0,进程占用内存大小为78;剩余空闲分区首地址为78,大小为946;未释放进程process-01。
③第三次内存分配:进程名为process-03,起始地址为78,进程占用内存大小为42;剩余空闲分区首地址为120,大小为904;
释放进程process-01和process-03
④第四次内存分配:进程名为process-02,起始地址为0,进程占用内存大小为93;剩余空闲分区首地址为93,大小为931;释放进程process-02。