操作系统第5次实验报告:内存管理

  • 姓名:程开
  • 学号:201821121060
  • 班级:计算1812

1. 记录内存空间使用情况

 

 

 

 

 

 

 pid记录进程号,size记录大小,start_addr记录起始地址,process_name记录进程名

*next记录下一个内存块

2. 记录空闲分区

 

 

 同上

3. 内存分配算法

 

 

 1 //执行分配内存
 2 void do_allocate_mem(AB *ab){
 3     int request = ab->size;
 4     FBT *tmp = free_block;
 5     while(tmp != NULL){
 6         if(tmp->size >= request){
 7             //分配
 8             ab->start_addr = tmp->start_addr;
 9             int shengyu = tmp->size - request;
10             tmp->size = shengyu;
11             tmp->start_addr = tmp->start_addr + request;
12             
13             return ;
14         }
15         tmp = tmp->next;
16     }
17 }
18 
19 int allocate_mem(AB *ab){
20     /*分配内存模块*/
21     FBT *fbt,*pre;
22     int request_size=ab->size;
23     fbt = pre = free_block;
24     //尝试寻找可分配空闲,具体结果在函数中有解释
25     int f = find_free_mem(request_size);
26     if(f == -1){
27         //不够分配
28         printf("空闲内存不足,内存分配失败!\n");
29         return -1;
30     }else{
31         if(f == 0){
32             //需要内存紧缩才能分配
33             memory_compact();
34         }
35         //执行分配
36         do_allocate_mem(ab);
37     }
38     //重新排布空闲分区
39     rearrange(ma_algorithm);
40     return 1;
41 } 
42 
43 //为进程分配内存 
44 int alloc_process(Prc prc){
45     AB *ab;
46     int ret;
47     ab = (AB*)malloc(sizeof(AB));
48     if(!ab) exit(-5);
49     /*为ab赋值 */ 
50     ab->next=NULL;
51     pid++;//记录id 
52     strcpy(ab->process_name,prc.process_name);
53     ab->pid = pid; 
54     ab->size=prc.size+rand()%ALLOC_SIZE;//随机分配内存 
55 
56     ret = allocate_mem(ab);        //从空闲分区分配内存,ret==1表示分配成功
57     if((ret == 1) && (allocated_block_head == NULL)){
58         /*如果此时allocated_block_head尚未赋值,则赋值*/
59         allocated_block_head = ab;
60         return 1;
61     }else if(ret == 1){
62         /*分配成功,将该分配块的描述插入已分配链表*/
63         ab->next = allocated_block_head;
64         allocated_block_head = ab;
65         return 2;
66     }else if(ret == -1){
67         //分配不成功
68         printf("\e[0;31;1m 内存分配失败! \e[0m\n");
69         free(ab);
70         return -1;
71     }
72     return 3;
73 }
  • 使用首次适配算法
  • 从最低地址的空闲分区开始找起,找到合适的便进行分配,内存空间按起始地址从小到大排序
  • 优点是查找速度快,缺点是内存碎片多

4. 内存释放算法

  1 //初始化空闲分区链表
  2 FBT *init_free_block(int mem_size){
  3     FBT *fb;
  4 
  5     fb = (FBT*)malloc(sizeof(FBT));
  6     if(fb==NULL){
  7         printf("No mem\n");
  8         return NULL;
  9     }
 10     fb->size = mem_size;
 11     fb->start_addr = DEFAULT_MEM_START;
 12     fb->next = NULL;
 13     return fb;
 14 }
 15 //释放链表节点
 16 int dispose(AB *free_ab){
 17     /*释放ab数据结构节点*/
 18     AB *pre,*ab;
 19     if(free_ab == allocated_block_head){
 20         //如果要是释放第一个节点
 21         allocated_block_head = allocated_block_head->next;
 22         free(free_ab);
 23         return 1;
 24     }
 25     pre = allocated_block_head;
 26     ab = allocated_block_head->next;
 27     while(ab!=free_ab){
 28         pre = ab;
 29         ab = ab->next;
 30     }
 31     pre->next = ab->next;
 32     free(ab);
 33     return 2;
 34 }
 35 
 36 //更新分区表
 37 int free_mem(AB *ab){
 38     /* 将ab所表示的已分配区归还,并进行可能的合并 */
 39     int algorithm = ma_algorithm;
 40     FBT *fbt,*pre,*work;
 41     fbt = (FBT*)malloc(sizeof(FBT));
 42     if(!fbt) return -1;
 43     fbt->size = ab->size;
 44     fbt->start_addr = ab->start_addr;
 45 
 46     //插至末尾
 47     work = free_block;
 48     if(work == NULL){
 49         free_block = fbt;
 50         fbt->next == NULL;
 51     }else{
 52         while(work ->next != NULL){
 53             work = work->next;
 54         }
 55         fbt->next = work->next;
 56         work->next = fbt;
 57     }
 58     //按地址重新排布
 59     rearrange_FF();
 60 
 61     //合并可能分区;即若两空闲分区相连则合并
 62     pre = free_block;
 63     while(pre->next){
 64         work = pre->next;
 65         if(pre->start_addr + pre->size == work->start_addr ){
 66             pre->size = pre->size + work->size;
 67             pre->next = work->next;
 68             free(work);
 69             continue;
 70         }else{
 71             pre = pre->next;
 72         }
 73     }
 74 
 75     //按照当前算法排序
 76     rearrange(ma_algorithm);
 77     return 1;
 78 }
 79 
 80 //找到pid对应的链表节点
 81 AB *find_process(int pid){
 82     AB *tmp = allocated_block_head;
 83     while(tmp != NULL){
 84         if(tmp->pid == pid){
 85             return tmp;
 86         }
 87         tmp = tmp->next;
 88     }
 89     printf("\e[0;31;1m 没有找到进程id为%d的进程! \e[0m\n",pid);
 90     return NULL;
 91 }
 92 
 93 int kill_process(int pid){
 94     AB *ab;
 95     ab = find_process(pid);
 96     if(ab!=NULL){
 97         free_mem(ab);    //释放ab所表示的分配表
 98         dispose(ab);    //释放ab数据结构节点
 99         return 0;
100     }else{
101         return -1;
102     }
103 }
  • 找到对应的链表节点,释放内存块

5. 运行结果

测试代码

 1 int main(int argc, char const *argv[]){
 2     int sel1,sel2; 
 3     int total=0; //记录分配内存的次数 
 4     free_block = init_free_block(mem_size);//初始化空闲区
 5     Prc prc[PROCESS_NUM];//存放要加载的进程
 6     init_program(prc,PROCESS_NUM);//对这几个程进程进行初始化 
 7     srand((unsigned)time(NULL));  
 8     for(int i=0;i<DATA_NUM;++i)
 9     {
10         /*
11            sel1=0表示为某进程分配内存空间 
12            sel1=1表示为释放某进程占用的内存空间 
13         */ 
14         sel1=rand()%2;
15         int count=0;
16         //统计三个进程中有多少个进程已经分配内存 
17         for(int j=0;j<PROCESS_NUM;++j){
18             if(prc[j].pid!=-1)
19                 count++;
20         }
21         //如果全部分配进程或者进程分配到达5次,那么就不能继续分配内存改为释放内存 
22         if((count==PROCESS_NUM && sel1==0)||total==5)
23             sel1=1;
24         //如果全部未分配进程,那么就不能继续释放内存 
25         if(count==0 && sel1==1)
26             sel1=0;
27         if(sel1==0)//为进程分配内存 
28         {
29             //随机找到一个未分配内存的进程 
30             do{
31                 sel2=rand()%PROCESS_NUM;
32             }while(prc[sel2].pid!=-1);
33             alloc_process(prc[sel2]);//分配内存空间 
34             prc[sel2].pid=pid;//改变标记 
35             total++;
36             display_mem_usage();//显示 
37         }
38         else//释放进程占用的内存空间 
39         {
40             //随机找到一个可释放进程 
41             do{
42                 sel2=rand()%PROCESS_NUM;
43             }while(prc[sel2].pid==-1);
44             kill_process(prc[sel2].pid);//释放内存空间 
45             prc[sel2].pid=-1;//改变标记 
46             display_mem_usage();//显示 
47         }
48     }
49 }

 

 

进程1  process-02起始地址0,大小82,进程2  process-01起始地址82,大小85, 随后释放进程

 

进程3  process-03起始地址0,大小65

进程4  process-01起始地址65,大小74

进程5  process-02起始地址65+74=139,大小44

然后剩余空闲的内存起始地址139+44=183,大小841

 

 

 

posted @ 2020-05-17 17:15  Amazing_C  阅读(273)  评论(0编辑  收藏  举报