操作系统第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的空间。

posted @ 2020-05-16 18:33  木澈  阅读(269)  评论(0编辑  收藏  举报