zoukankan      html  css  js  c++  java
  • 操作系统第五次实验报告——内存管理

    0 个人信息

    • 张樱姿
    • 201821121038
    • 计算1812

    1 实验目的

    • 通过编程进一步了解内存管理。

    2 实验内容

    • 在服务器上用Vim编写一个程序:仿真实现某个内存管理算法,测试给出结果,并对运行结果进行解释。

    3 实验报告

      3.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 //进程分配内存块链表的首指针
    11 AB *allocated_block_head = NULL; 

      3.2 记录空闲分区

       同样也使用链表来记录空闲分区。

    1 //每个空闲块
    2 typedef struct free_block_type{
    3     int size;            //空闲块大小
    4     int start_addr;   //空闲块起始地址
    5     struct free_block_type *next;   //指向下一个空闲块
    6 }FBT;
    7 
    8 //指向内存中空闲块链表的首指针
    9 FBT *free_block;        

      3.3 内存分配算法

       最佳分配算法(Best Fit Allocation)的原理是空闲分区列表按照大小排序,在分配时,查找一个合适的分区(分配n字节分区时,查找并使用不小于n的最小空间分区);在释放时,查找并且合并临近的空闲分区(如果找到的话)。

     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 //分配内存模块
    20 int allocate_mem(AB *ab){
    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("空闲内存不足,内存分配失败!
    ");
    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 void rearrange_BF(){
    45     if(free_block == NULL || free_block->next == NULL)
    46         return;
    47     FBT *t1,*t2,*head;
    48     head = free_block;
    49     //遍历整个空闲块列表,比较找到最小的一块空闲块
    50     for(t1 = head->next;t1;t1 = t1->next){
    51         for(t2 = head;t2 != t1;t2=t2->next){
    52             if(t2->size > t2->next->size){
    53                 int tmp = t2->start_addr;
    54                 t2->start_addr = t2->next->start_addr;
    55                 t2->next->start_addr = tmp;
    56 
    57                 tmp = t2->size;
    58                 t2->size = t2->next->size;
    59                 t2->next->size = tmp;
    60             }
    61         }
    62     }
    63 }

      3.4 内存释放算法

     1 //释放链表节点
     2 int dispose(AB *free_ab){
     3     AB *pre,*ab;
     4     if(free_ab == allocated_block_head){
     5         //如果要释放第一个节点
     6         allocated_block_head = allocated_block_head->next;
     7         free(free_ab);
     8         return 1;
     9     }
    10     pre = allocated_block_head;
    11     ab = allocated_block_head->next;
    12     while(ab!=free_ab){
    13         pre = ab;
    14         ab = ab->next;
    15     }
    16     pre->next = ab->next;
    17     free(ab);
    18     return 2;
    19 }
    20 
    21 //更新分区表
    22 int free_mem(AB *ab){
    23     //将ab所表示的已分配区归还,并进行可能的合并
    24     int algorithm = ma_algorithm;
    25     FBT *fbt,*pre,*work;
    26     fbt = (FBT*)malloc(sizeof(FBT));
    27     if(!fbt) return -1;
    28     fbt->size = ab->size;
    29     fbt->start_addr = ab->start_addr;
    30 
    31     //插至末尾
    32     work = free_block;
    33     if(work == NULL){
    34         free_block = fbt;
    35         fbt->next == NULL;
    36     }else{
    37         while(work ->next != NULL){
    38             work = work->next;
    39         }
    40         fbt->next = work->next;
    41         work->next = fbt;
    42     }
    43     //按地址重新排布
    44     rearrange_BF();
    45 
    46     //合并可能分区;即若两空闲分区相连则合并
    47     pre = free_block;
    48     while(pre->next){
    49         work = pre->next;
    50         if(pre->start_addr + pre->size == work->start_addr ){
    51             pre->size = pre->size + work->size;
    52             pre->next = work->next;
    53             free(work);
    54             continue;
    55         }else{
    56             pre = pre->next;
    57         }
    58     }
    59     //按照当前算法排序
    60     rearrange(ma_algorithm);
    61     return 1;
    62 }
    63 
    64 //释放已分配的内存空间,删除描述该进程分配到的内存块的节点
    65 int kill_process(int pid){
    66     AB *ab;
    67     ab = find_process(pid);
    68     if(ab!=NULL){
    69         //释放ab所表示的分配表
    70         free_mem(ab);    
    71         //释放ab数据结构节点
    72         dispose(ab);    
    73         return 0;
    74     }else{
    75         return -1;
    76     }
    77 }

      3.5 运行结果

        3.5.1 产生测试数据

          随机为3个进程分配、释放内存10次以上,即随机产生10组以上数据。

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

        3.5.2 解释结果

         初始的空闲块大小1024KB,

         ①第一次分配结果:

         为PID为1的进程分配大小为24KB的内存空间,起始地址为0,分配完成后的空闲空间为1000KB,起始地址为24。

        ②第二次分配结果:

         为PID为2的进程分配大小为74KB的内存空间,起始地址为24,分配完成后的空闲空间为926KB,起始地址为98。

        ③第三次分配结果:

        为PID为3的进程分配大小为36KB的内存空间,起始地址为98,分配完成后的空闲空间为890KB,起始地址为134。     

        ④第四次分配结果:

        将PID为3的进程释放,空闲空间变为926KB,起始地址为98。

        ⑤第五次分配结果:

         将PID为1的进程释放,空闲空间变为两块,一块大小926KB,起始地址为98。另一块大小24KB,起始地址为0。

    4 References

      

        

  • 相关阅读:
    关于如何触发控件的事件
    MaxScript转换图像格式
    MaxScript装B技巧一则
    MaxScript.Net接收本地端口的消息执行
    MaxScript创建十二面体的代码
    MaxScript中GW使用范例一则
    Max里,Mesh真是高级自由度啊
    显示当前秒数的MaxScript
    Max2010的activex以及.net界面乱码解决方式
    半夜失眠,码点关于技术美术的字
  • 原文地址:https://www.cnblogs.com/MilkoSilver/p/12904806.html
Copyright © 2011-2022 走看看