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

• 姓名：倪晓东
• 学号：201821121020
• 班级： 计算1811

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

/*记录内存空间使用情况，每个进程分配到的内存块描述*/
struct allocated_block
{
int pid;
int size;                //进程大小
char process_name[PROCESS_NAME_LEN];  //进程名
struct allocated_block *next;   //指向下一个进程控制块
};


# 2. 记录空闲分区

//空闲分区，描述每一个空闲块的数据结构
struct free_block_type
{
int size;        //空闲块大小
struct free_block_type *next;  //指向下一个空闲块
};
//指向内存中空闲块链表的首地址
struct free_block_type *free_block= NULL;


空闲分区链表：

//按首次适配算法重新整理内存空闲块链表，按空闲块首地址排序
int rearrange_FF()
{
struct free_block_type *forehand,*pre,*rear;
int i;
return -1;
for(i= 0;i< free_block_count-1;i++)
{
pre= forehand->next;
rear= pre->next;
while(pre->next!= NULL)
{
{
//比较空闲链表中第一个空闲块与第二个空闲块的开始地址的大小
pre= forehand->next;
rear= pre->next;
}
{
//比较链表中其它相邻两个结点的开始地址的大小
pre->next= rear->next;
forehand->next= rear;
rear->next= pre;
forehand= rear;
rear= pre->next;
}
else
{
forehand= pre;
pre= rear;
rear= rear->next;
}
}
}
return 0;
}


# 3. 内存分配算法

//按照首次适应算法给新进程分配内存空间
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. 内存释放算法

int exit()
{
struct allocated_block *allocated_ab,*allocated_pre;
struct free_block_type *free_ab,*free_pre;
free_pre= free_block;
if(free_pre!= NULL)   //链表不为空
{
free_ab= free_pre->next;
while(free_ab!= NULL)
{
free(free_pre);   //释放当前节点
free_pre= free_ab;
free_ab= free_ab->next; //节点后移
}
}
if(allocated_pre!= NULL)
{
allocated_ab= allocated_pre->next;
while(allocated_ab!= NULL)
{
free(allocated_pre);  //释放节点
allocated_pre= allocated_ab;
allocated_ab= allocated_ab->next;  //节点后移
}
}
allocated_ab= allocated_ab->next;
return 0;
}


void kill_process()
{
struct allocated_block *ab;
int pid;
printf("Kill Process,pid=");//删除进程号为
scanf("%d",&pid);
getchar();
ab= find_process(pid);  //找到pid对应的链表节点
if(ab!= NULL)
{
free_mem(ab);  //释放ab所表示的分配区
dispose(ab);   //释放ab数据结构结点
}
}


struct allocated_block* find_process(int pid)
{
if(ab== NULL)
{
printf("不存在！\n");
return NULL;
}
while(ab->pid!= pid&&ab->next!= NULL)//查找整个链表
ab= ab->next;
if(ab->next== NULL&&ab->pid!= pid)//找不到
{
printf("error！\n");
return NULL;
}
return ab;
}


# 5. 运行结果

（1）产生测试数据

设置内存大小为200，每次为进程分配1-20内存大小：

（2）解释结果

如图所示，创建的第一个进程号PID=1，进程名称为PEOCESSNAME-01，内存起始地址为0，内存大小为2，空闲区首地址为2，剩余内存198。

如图所示，创建的第二个进程号PID=2，进程名称为PEOCESS-02，内存起始地址为2，分配到的内存大小为8，空闲区首地址为10，剩余内存190。

如图所示，创建的第二个进程号PID=3，进程名称为PEOCESS-03，内存起始地址为10，分配到的内存大小为15，空闲区首地址为25，剩余内存175。

如图所示，创建的第二个进程号PID=4，进程名称为PEOCESS-04，内存起始地址为25，分配到的内存大小为1，空闲区首地址为26，剩余内存174。

小结：

首次适配算法从空闲区的第一个表目起查找该表，把最先能够满足要求的空闲区分配给进程，这种方法目的在于减少查找时间。为适应这种算法，空闲区链中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区，在低址空间造成许多小的空闲区，在高地址空间保留大的空闲区。但是在实际使用过程中，由于优先使用低址的可用空闲区，低址部分被不断进行分配，但又不能保证刚好完全利用，所以会留下很多不能被使用小空闲区，而且每次为进程分配内存从低址开始寻找，就要和这些小空闲区适配，会影响速率。

posted @ 2020-05-17 16:20  Linial  阅读(1545)  评论(0编辑  收藏  举报