操作系统第5次实验报告:内存管理
- 姓名:白晓
- 学号:201821121035
- 班级:计算1812
1. 记录内存空间使用情况
1 /*每个进程分配到的内存块描述*/ 2 typedef struct allocated_block{ 3 int pid; 4 int size; 5 int start_addr; 6 char process_name[NAME_LEN]; 7 struct allocated_block *next; 8 }AB; 9 /*进程分配内存块链表的首指针*/ 10 AB *allocated_block_head = NULL;
建立一个链表来记录内存空间的使用情况。定义一个结构体allocated_block来存放加载到内存中的进程,定义一个全局指针变量allocated_block_head来指向链表的头结点。
2. 记录空闲分区
1 /*描述每一个空闲块的数据结构*/ 2 typedef struct free_block_type{ 3 int size; 4 int start_addr; 5 struct free_block_type *next; 6 }FBT; 7 FBT *free_block;//指向内存中空闲块链表的首指针
建立一个链表来记录空闲分区。定义一个结构体free_block_type来存放空闲内存块,定义一个全局指针变量free_block来指向链表的头结点,初始化内存后,空闲分区块从小到大排序。
3. 内存分配算法
1 void do_allocate_mem(AB *ab){ 2 int request = ab->size; 3 FBT *tmp = free_block; 4 while(tmp != NULL){ 5 if(tmp->size >= request){ 6 //分配 7 ab->start_addr = tmp->start_addr; 8 int shengyu = tmp->size - request; 9 tmp->size = shengyu; 10 tmp->start_addr = tmp->start_addr + request; 11 return ; 12 } 13 tmp = tmp->next; 14 } 15 } 16 17 int allocate_mem(AB *ab){ 18 FBT *fbt,*pre; 19 int request_size=ab->size; 20 fbt = pre = free_block; 21 int f = find_free_mem(request_size); 22 if(f == -1){ 23 printf("空闲内存不足,内存分配失败!\n"); 24 return -1; 25 }else{ 26 if(f == 0){ 27 memory_compact(); 28 } 29 do_allocate_mem(ab); 30 } 31 rearrange(ma_algorithm); 32 return 1; 33 } 34 35 void rearrange_FF(){ 36 FBT *t1,*t2,*head; 37 head = free_block; 38 for(t1 = head->next;t1;t1 = t1->next){ 39 for(t2 = head;t2 != t1;t2=t2->next){ 40 if(t2->start_addr > t2->next->start_addr){ 41 int tmp = t2->start_addr; 42 t2->start_addr = t2->next->start_addr; 43 t2->next->start_addr = tmp; 44 tmp = t2->size; 45 t2->size = t2->next->size; 46 t2->next->size = tmp; 47 } 48 } 49 } 50 }
根据首次适配算法在空闲分区链表中查找合适空闲分区进行分配,如果找到可满足空闲分区,则分割;如果找不可满足需要的空闲分区,则采用内存紧缩技术,进行空闲分区的合并,然后再分配。
4. 内存释放算法
1 int dispose(AB *free_ab){ 2 AB *pre,*ab; 3 if(free_ab == allocated_block_head){ 4 allocated_block_head = allocated_block_head->next; 5 free(free_ab); 6 return 1; 7 } 8 pre = allocated_block_head; 9 ab = allocated_block_head->next; 10 while(ab!=free_ab){ 11 pre = ab; 12 ab = ab->next; 13 } 14 pre->next = ab->next; 15 free(ab); 16 return 2; 17 } 18 19 int free_mem(AB *ab){ 20 int algorithm = ma_algorithm; 21 FBT *fbt,*pre,*work; 22 fbt = (FBT*)malloc(sizeof(FBT)); 23 if(!fbt) return -1; 24 fbt->size = ab->size; 25 fbt->start_addr = ab->start_addr; 26 work = free_block; 27 if(work == NULL){ 28 free_block = fbt; 29 fbt->next == NULL; 30 }else{ 31 while(work ->next != NULL){ 32 work = work->next; 33 } 34 fbt->next = work->next; 35 work->next = fbt; 36 } 37 rearrange_FF(); 38 39 pre = free_block; 40 while(pre->next){ 41 work = pre->next; 42 if(pre->start_addr + pre->size == work->start_addr ){ 43 pre->size = pre->size + work->size; 44 pre->next = work->next; 45 free(work); 46 continue; 47 }else{ 48 pre = pre->next; 49 } 50 } 51 rearrange(ma_algorithm); 52 return 1; 53 } 54 55 int kill_process(int pid){ 56 AB *ab; 57 ab = find_process(pid); 58 if(ab!=NULL){ 59 free_mem(ab); //释放ab所表示的分配表 60 dispose(ab); //释放ab数据结构节点 61 return 0; 62 }else{ 63 return -1; 64 } 65 }
释放链表结点,利用free()不断释放结点,更新分区表,进行可能的合并,对空闲链表进行排序,并合并相邻空闲链表。
5. 运行结果
(1)产生测试数据
测试数据:
int main(int argc, char const *argv[]){ /* code */ int sel1,sel2; int total=0; //记录分配内存的次数 free_block = init_free_block(mem_size); //初始化空闲区 Prc prc[PROCESS_NUM];//存放要加载的进程 init_program(prc,PROCESS_NUM);//对这几个程进程进行初始化 srand( (unsigned)time( NULL ) ); for(int i=0;i<DATA_NUM;++i) { /*sel1=0表示为某进程分配内存空间,sel1=1表示为释放某进程占用的内存空间*/ 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)解释结果
每一次内存分配或释放,内存的示意图是怎样的。给出4组分析即可。
第一组:为process-02分配了从0开始,大小为98的内存单元,分配后空闲分区内存剩余地址为从28开始,大小为926的空间。
第二组:释放了process-02从0开始,大小为98的内存单元,释放后空闲分区内存剩余地址为从142开始,大小为882的空间。
第三组:为process-03分配了从0开始,大小为64的内存单元,分配后空闲分区内存剩余地址为从64开始,大小为960的空间。
第四组:为process-02分配了从0开始,大小为43的内存单元,分配后空闲分区内存剩余地址为从43开始,大小为981的空间。