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

  • 姓名:李宗政
  • 学号:201821121029
  • 班级:计算1811

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

创建一个结构体,分配到内存进行描述,其中各自含义包括了:pid号,s是进程,start,process_name[]是进程名数组

{
    int pid;
    int size;         //进程大小
    int start_addr;   //进程分配到的内存块的起始地址
    char process_name[PROCESS_NAME_LEN];  //进程名
    struct allocated_block *next;   //指向下一个进程控制块
};

2. 记录空闲分区

空闲分区表

struct free_block_type
{
    int size;        //空闲块大小
    int start_addr;  //空闲块起始位置
    struct free_block_type *next;  //指向下一个空闲块
};

3. 内存分配算法

按照最坏适应算法给新进程分配内存空间:

最差适应算法(WorstFit):从全部空闲区中找出能满足作业要求的、且大小最大的空闲分区,从而使链表中的结点大小趋于均匀,适用于请求分配的内存大小范围较窄的系统。为适应此算法,空闲分区表(空闲区链)中的空闲分区按大小从大到小进行排序,自表头开始查找到第一个满足要求的自由分区分配。该算法保留小的空闲区,尽量减少小的碎片产生。

int allocate_WF(struct allocated_block *ab)
{
    int ret;
    struct free_block_type *wf= free_block;
    if(wf== NULL)
        return -1;
    if(wf->size>= ab->size)
        allocate(NULL,wf,ab);
    else if(current_free_mem_size>= ab->size)
        ret= mem_retrench(ab);
    else
        ret= -2;
    rearrange_WF();
    return ret;
}

按照最佳适应算法给新进程分配内存空间

最佳适应算法(BestFit):从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。该算法保留大的空闲区,但造成许多小的空闲区。

int allocate_BF(struct allocated_block *ab)
{
    int ret;
    struct free_block_type *pre= NULL,*bf= free_block;
    if(bf== NULL)
        return -1;
    while(bf!= NULL)
    {
        if(bf->size>= ab->size)
        {
            ret= allocate(pre,bf,ab);
            break;
        }
        pre= bf;
        pre= pre->next;
    }
    if(bf== NULL&&current_free_mem_size> ab->size)
        ret= mem_retrench(ab);
    else
        ret= -2;
    rearrange_BF();
   

按照首次适应算法给新进程分配内存空间:

首次适应算法(FirstFit):从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法的目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。

int allocate_FF(struct allocated_block *ab)
{
    int ret;
    struct free_block_type *pre= NULL,*ff= free_block;
    if(ff== NULL)
        return -1;
    while(ff!= NULL)
    {
        if(ff->size>= ab->size)
        {
            ret= allocate(pre,ff,ab);
            break;
        }
        pre= ff;
        pre= pre->next;
    }
    if(ff== NULL&&current_free_mem_size> ab->size)
        ret= mem_retrench(ab);
    else
        ret= -2;
    rearrange_FF();
    return ret;
}

4. 内存释放算法

释放ab数据结构结点:

int dispose(struct allocated_block *free_ab)
{
    struct allocated_block *pre,*ab;
    if(free_block== NULL)
        return -1;
    if(free_ab== allocated_block_head)   //如果要释放第一个结点
    {
        allocated_block_head= allocated_block_head->next;
        free(free_ab);
    }
    else
    {
        pre= allocated_block_head;
        ab= allocated_block_head->next; 
        //找到free_ab
        while(ab!= free_ab)
        {
            pre= ab;
            ab= ab->next;
        }
        pre->next= ab->next;
        free(ab);
    }
    return 1;
}

删除进程,归还分配的存储空间,并删除描述该进程内存分配的结点:

void kill_process(int x)
{
    struct allocated_block *ab;
    int pid;
    
    pid=x;
    
    ab= find_process(pid);
    if(ab!= NULL)
    {
        free_mem(ab); 
        dispose(ab);  
    }
}

5. 运行结果

(1)产生测试数据

 

 

 

(2)解释结果

  从最开始的地址0创建了size为41的空间,往后以此类推,以上一个PId创建的空间加他的地址为下一个的首地址一共循环十次。

原文地址:https://www.cnblogs.com/Lucienight/p/12905724.html