操作系统第5次实验报告:内存管理
- 姓名:江磊
- 学号:201821121059
- 班级:计算1812
1. 记录内存空间使用情况
用结构体来分别定义,进程的标识符、进程大小、进程名、进程分配的起始地址以及下一块。
typedef struct allocated_block{ int pid;//进程的标识符 int size;//进程块大小 int start_addr;//进程被分配的起始地址 char process_name[PROCESS_NAME_LEN];//进程名 struct allocated_block *next;//指针指向的下一个块 }AB;
2. 记录空闲分区
同样用一个结构体来标识进程的标识符、进程被分配的起始地址、以及指针指向的下一块
typedef struct free_block_type{ int size;//进程的标识符 int start_addr;//进程被分配的起始地址 struct free_block_type *next;//指针指向的下一个块 }FBT;
3. 内存分配算法
使用最佳适应性算法:能够从所有适合的空闲内存块找出最小的空闲内存块,这种方法的优点是产生的空闲内存块碎片最小。
void rearrange_BF(){ if(free_block == NULL || free_block->next == NULL) return; FBT *t1,*t2,*head; head = free_block; for(t1 = head->next;t1;t1 = t1->next){ for(t2 = head;t2 != t1;t2=t2->next){ if(t2->size > t2->next->size){ int tmp = t2->start_addr; t2->start_addr = t2->next->start_addr; t2->next->start_addr = tmp; tmp = t2->size; t2->size = t2->next->size; t2->next->size = tmp; } } } }
4. 内存释放算法
int dispose(AB *free_ab){ AB *pre,*ab; if(free_ab == allocated_block_head){ allocated_block_head = allocated_block_head->next; free(free_ab); return 1; } pre = allocated_block_head; ab = allocated_block_head->next; while(ab!=free_ab){ pre = ab; ab = ab->next; } pre->next = ab->next; free(ab); return 2; } int free_mem(AB *ab){ int algorithm = ma_algorithm; FBT *fbt,*pre,*work; fbt = (FBT*)malloc(sizeof(FBT)); if(!fbt) return -1; fbt->size = ab->size; fbt->start_addr = ab->start_addr; work = free_block; if(work == NULL){ free_block = fbt; fbt->next == NULL; }else{ while(work ->next != NULL){ work = work->next; } fbt->next = work->next; work->next = fbt; } rearrange_BF(); pre = free_block; while(pre->next){ work = pre->next; if(pre->start_addr + pre->size == work->start_addr ){ pre->size = pre->size + work->size; pre->next = work->next; free(work); continue; }else{ pre = pre->next; } } rearrange(ma_algorithm); return 1; } AB *find_process(int pid){ AB *tmp = allocated_block_head; while(tmp != NULL){ if(tmp->pid == pid){ return tmp; } tmp = tmp->next; } printf("\e[0;31;1m 没有找到进程id为%d的进程! \e[0m\n",pid); return NULL; } int kill_process(int pid){ AB *ab; ab = find_process(pid); if(ab!=NULL){ free_mem(ab); dispose(ab); return 0; }else{ return -1; } }
5. 运行结果
(1)产生测试数据
int main(int argc, char const *argv[]){ int flag1,flag2; int total=0; free_block = init_free_block(mem_size); Pro pro[3]; init_program(pro,3); srand( (unsigned)time( NULL ) ); for(int i=0;i<DATA_NUM;++i) { flag1=rand()%2; int count=0; for(int j=0;j<3;++j){ if(pro[j].pid!=-1) count++; } if((count==3 && flag1==0)||total==10) flag1=1; if(count==0 && flag1==1) flag1=0; if(flag1==0) { do{ flag2=rand()%3; }while(pro[flag2].pid!=-1); new_process(pro[flag2]); pro[flag2].pid=pid; total++; view(); } else { do{ flag2=rand()%3; }while(pro[flag2].pid==-1); kill_process(pro[flag2].pid); pro[flag2].pid=-1; view(); } } } FBT *init_free_block(int mem_size){ FBT *fb; fb = (FBT*)malloc(sizeof(FBT)); if(fb==NULL){ printf("无内存\n"); return NULL; } fb->size = mem_size; fb->start_addr = MEM_START; fb->next = NULL; return fb; }
(2)解释结果
初始化的空闲分区的内存范围为0到1024,
第一次操作为进程pro2分配了从0开始,大小为21的一块内存单元,空闲分区内存地址从21开始,大小为1003。
第二次操作为进程pro3分配了从21开始,大小为92的一块内存单元,分空闲分区内存地址从113开始,大小为911。
第三次操作为进程pro1分配了从113开始,大小为49的一块内存单元,空闲分区内存地址从162开始,大小为862。
第四次释放pro3,得到的孔空闲地址: