当前位置:文档之家› 可变分区存储管理方式的内存分配回收

可变分区存储管理方式的内存分配回收

实验报告操作系统可变分区存储管理方式的内存分配回收班级:XXXXXXXXXXXX学号:XXXXXXXXXXXX姓名:XXXXXX日期:XXXX.XX.XX版本历史Revisions History目录1引言41.1实验目的41.2参考文档42可变分区存储管理52.1实验原理分析52.2设计思路52.3源程序62.4重要结构体说明102.5重要变量说明102.6结果112.7测试方法对结果的分析112.8接口122.8.1接口设计说明122.9任务设计122.9.1流程图121 引言1.1实验目的通过首次适应算法、最佳适应算法和最坏适应算法实现主存空间的分配,可以使开发人员更好地理解存储分配算法。

1.2参考文档1.操作系统2.3.1节空闲存储区表2.操作系统2.3.2节首次适应法(1.分配算法,2.回收算法)2 可变分区存储管理2.1实验原理分析在可变分区模式下,在系统初启且用户作业尚未装入主存储器之前,整个用户区是一个大空闲分区,随着作业的装入和撤离,主存空间被分成许多分区,有的分区被占用,而有的分区时空闲的。

为了方便主存空间的分配和去配,用于管理的数据结构可由两张表组成:“已分配区表”和“未分配区表”。

在“未分配表中”将空闲区按长度递增顺序排列,当装入新作业时,从未分配区表中挑选一个能满足用户进程要求的最小分区进行分配。

这时从已分配表中找出一个空栏目登记新作业的起始地址和占用长度,同时修改未分配区表中空闲区的长度和起始地址。

当作业撤离时已分配区表中的相应状态变为“空”,而将收回的分区登记到未分配区表中,若有相邻空闲区再将其连接后登记。

2.2设计思路1、分配算法:采用首次适应法为作来分配大小为size的内存空间时,总是从表的起始端的低地址部分开始查找,当第一次找到大于或等于申请大小的空闲区时,就按所需大小分配给作业。

如果分配后原空闲区还有剩余空间,就修改原存储区表项的m_size和m_addr,使它记录余下的“零头”。

如果作业所需空间正好等于该空闲区大小,那么该空闲区表项的m_size就成为0,接下来要删除表中这个“空洞”,即将随后的各非零表项依次上移一个位置。

2、回收算法:当某一作业回收以前所分配到的内存时,就要将该内存区归还给系统,使其成为空闲区而可被其它作来使用。

回收时如释放区与邻近的空闲区相衔接,要将它们合并成较大的空闲区,否则空闲区将被分割得超来越小,最终导致不能利用;另外,空闲区个数越来越多,也会使空闲区登记表溢出。

2.3源程序/*| 如不会使用文件输入/输出,也不会使用I/O转向做输入和输出结果文件,| 可以手再抄输出结果后后再输到文件中,实验报告的文字内容由自己掌握,能多能少。

*/#include<stdio.h>#include<malloc.h>/*表的定义*/#define N 5#define MEMSIZE 1000typedefstruct map{unsigned m_size;char *m_addr;};struct map coremap[N];/* coremap表的初始化程序*/void initcoremap(char *addr, unsigned size){unsigned i;printf("init coremap, first addr: %d\n", addr);coremap[0].m_size = size;coremap[0].m_addr = addr;for(i = 1; i < N; i++){coremap[i].m_size = 0;coremap[i].m_addr = 0;}}/* 输出表的内容*/void printcoremap(void){unsigned i;/* 打印coremap表中各项的m_size和m_addr */for(i = 0; i < N; i++){printf("coremap[%d].m_addr=%d ", i, coremap[i].m_addr); printf("coremap[%d].m_size=%d\n", i, coremap[i].m_size); }}/* 首次适应的分配函数*/char *fmalloc(unsigned size){registerchar *a;registerstruct map *bp;for (bp = coremap; bp->m_size; bp++){if(bp->m_size >= size){a = bp->m_addr;bp->m_addr += size; /* 修改表项的首地址*/if((bp->m_size -= size) == 0) /* 有正好大小的空闲区*/ do{bp++;(bp - 1)->m_addr = bp->m_addr; /* 修改表项的首地址*/}while((bp - 1)->m_size = bp->m_size);/* 打印分配内存空间的m_size和m_addr*/printf("fmalloc size: %d, addr:%d\n", size, a);return(a);}}return(0);}/* 首次适应的回收函数*/void ffree(unsigned size, char *addr){struct map *bp;char *a, *t;unsigned tt;printf("ffree mem size=%u, addr=%u\n", size, addr);a = addr;for (bp = coremap; bp->m_addr <= a && bp->m_size != 0; bp++);if (bp > coremap && (bp - 1)->m_addr + (bp - 1)->m_size == a) /* 情况1、2 */ {(bp - 1)->m_size += size; /* 情况1*/if (a + size == bp->m_addr) /* 情况2*/{(bp - 1)->m_size += bp->m_size;while (bp->m_size){bp++;(bp - 1)->m_addr = bp->m_addr;(bp - 1)->m_size = bp->m_size;}}}else{if (a + size == bp->m_addr && bp->m_size) /* 情况3*/{bp->m_addr -= size;bp->m_size += size;}elseif (0 != size) /* 情况4*/{do{t = bp->m_addr;bp->m_addr = a;a = t;tt = bp->m_size;bp->m_size = size;bp++;}while (size = tt);}}}/* 主程序的框架*/int main(void){char *mymem;int size;int addr;char cmdchar;char c="";if ((mymem = malloc(MEMSIZE)) == NULL){printf("Not enough memory to allocate buffer\n"); exit(1);}initcoremap(mymem, MEMSIZE);while(c != 'q'){do{c = getchar();}while(c == '\n' || c == '\t' || c == ' ');cmdchar = c;switch (cmdchar){case'm':/* 分配空间*/scanf("%u", &size);fmalloc(size);break;case'f':/* 释放空间*/scanf("%u %u", &size, &addr);ffree(size, mymem + addr);break;case'p':printcoremap();break;default:/* 其它字母退出*/break;}}free(mymem);return 0;}2.4重要结构体说明空闲存储区表可采用结构数组的形式,采用的数据结构形式为:typedef struct map{unsigned m_size;char *m_addr;};m_size:是空闲分区的长度m_addr:是空闲分区的起始地址2.5重要变量说明coremap[N]:是空闲存储区表2.6结果2.7测试方法对结果的分析1、连续分配3个100长度的分区,剩下700长度的分区2、从头释放掉一个100长度的分区,里面有两个可用的分区,一个是100长度的分区,一个是700长度的分区3、程序运行的结果,与设计思路一致。

2.8接口2.8.1 接口设计说明2.9任务设计2.9.1 流程图。

相关主题