OS 内存管理
-
实验目的
-
通过实验加强对内存管理方法的理解和掌握。
-
实验内容
编写程序实现采用可变分区方法管理内存。 -
实验要求
1、在该实验中,采用可变分区方式完成对存储空间的管理(即存储空间的分配与回收工作)。
2、设计用来记录主存使用情况的数据结构:已分区表和空闲分区表或链表。
3、在设计好的数据结构上设计一个主存分配算法。
4、在设计好的数据结构上设计一个主存回收算法。其中,若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里。
5、(附加)若需要可以实现程序的浮动,对内存空间进行紧凑。 -
内存管理算法:
- 数据结构
- 模拟中申请一个较大的buff(char buf[1024]),模拟程序的内存非配地址为buf的编号(0-1023)。
- m {int pre;int len;int used;int flag;}
- pcb {int pid;m mem;}
- list mfree 空闲分区表
- list mused 已分配分区表
- 分配算法
遍历空闲分区表,满足即分配。 - 回收合并算法
合并类型- up & down
- up
- down
- just insert
- 紧缩操作
- 对空闲分区链表排序(升序)
- 复制分区内容从 buf[0]开始,并更新已分配表分区的起始地址
- 清空空闲分区表,插入buf剩余大小的一个分区
- 数据结构
-
code:
#include<iostream> #include<iostream> #include<cstring> #include<cstdio> #include<list> using namespace std; //管理的内存空间 const int MAX=200; char buf[MAX]; struct DM { //上界+长度 int pre; int len; //使用标志 int used; //分配标志,flag=-1分配失败 int flag; }; struct PCB { int pid;//进程号 DM mem;//内存分配,表示从buf制定一段长度给该pcb //内存紧缩,仅考虑新创建进程内存不足时,对mem进行紧缩(copy) }; //pcb中使用new list直接使用dm //内存管理 list<DM>mused; list<DM>mfree; //进程信息 list<PCB>pcb; //内存分配 MD.flag==-1:error DM allocate(int len) { DM getone; getone.flag=-1; cout<<mfree.size()<<endl; //轮寻空闲分区表,满足即分配 for(list<DM>::iterator it=mfree.begin();it!=mfree.end();it++) { if(it->len>len) { cout<<it->len<<"-"<<len<<endl; getone.pre=it->pre; getone.len=len; getone.used=1; mused.push_back(getone); getone.flag=0; it->pre+=len; it->len-=len; if(it->len==0) mfree.erase(it); } } return getone; } //real time merge ,so do not need to iterate or recurse //free from used //内存释放与回收 void del(DM m) { //从free list中查找pos=pre|pre+len //1.up merge //2.down merge //3.up&down merge //4.do not need to merge //查找上 和 下 相邻 cout<<"mem del..."<<endl; list<DM>::iterator up=mfree.end(); list<DM>::iterator next=mfree.end(); list<DM>::iterator cur=mused.end(); //在已分配分区表中,找到该分区 for(list<DM>::iterator it=mused.begin();it!=mused.end();it++) if(it->pre==m.pre) { cur=it; break; } //不存在该分区 if(cur==mused.end()) { cout<<"error:can not find mem in used"<<endl; return; } //空闲分区查找是否存在上空闲和下空闲分区 for(list<DM>::iterator it=mfree.begin();it!=mfree.end();it++) { if(it->pre+it->len==m.pre) up=it; else if(it->pre==m.pre+m.len) next=it; else if(up!=mfree.end()&&next!=mfree.end()) break; } //合并 四种类型 cout<<"merge type:"<<endl; if(up!=mfree.end()&&next!=mfree.end()) { cout<<"up & down"<<endl; up->len+=cur->len; up->len+=next->len; mfree.erase(next); //up down }else if(up!=mfree.end()) { cout<<"up"<<endl; up->len+=cur->len; //up }else if(next!=mfree.end()) { cout<<"down"<<endl; next->pre=cur->pre; next->len+=cur->len; //down }else { cout<<"insert"<<endl; mfree.push_back(*cur); } //在已分配表中删除该分区 mused.erase(cur); } bool ascend(DM a,DM b) { return a.pre<b.pre; } //紧缩操作 void compact() { cout<<"compact before:"<<endl; for(int i=0;i<100;i++) cout<<buf[i]<<" "; cout<<endl; //对used list 排序,从小开始紧缩 mused.sort(ascend); int pos=0; //直接对按地址从小到大排好序的分区移动 for(list<DM>::iterator it=mused.begin();it!=mused.end();it++) { strcpy(buf+pos,buf+it->pre); it->pre=pos; pos+=it->len; } //删除所有的空闲分区,重新添加整合后的一个空闲分区 mfree.clear(); DM mf; mf.pre=pos; mf.len=MAX-pos; mfree.push_back(mf); cout<<"compact after:"<<endl; for(int i=0;i<100;i++) cout<<buf[i]<<" "; cout<<endl; } /* * procedure: * loop: * create process and make sure the mem size * input some strings * when the mem size is not enough * then compact * * */ void show() { cout<<endl; cout<<"status:"<<endl; cout<<"pcb:\t mfree:\t mused:"<<endl; cout<<pcb.size()<<"\t"<<mfree.size()<<"\t"<<mused.size()<<endl; cout<<endl; } int main() { DM membuf; membuf.pre=0; membuf.len=MAX; membuf.used=0; mfree.push_back(membuf); PCB pcb_tmp; int len,w,pid; char tmp[100]; show(); //freopen("in","r",stdin); while(true) { cout<<"------------------------"<<endl; cout<<"create 0 pidnum or kill 1 pidnum or compact 2 or 3 exit"<<endl; cin>>w; if(w==0) { cout<<"create process ,input(pid,mem size,brief)"<<endl; cin>>pcb_tmp.pid>>pcb_tmp.mem.len>>tmp; if(strlen(tmp)>pcb_tmp.mem.len) { //内存使用不能超出所申请的大小 cout<<"error:mem overflow"<<endl; continue; } //分配指定大小内存 pcb_tmp.mem=allocate(pcb_tmp.mem.len); if(pcb_tmp.mem.flag==0)//successful { //加入pcb管理 pcb.push_back(pcb_tmp); //copy 将进程内容复制到申请的内存中 strcpy(buf+pcb_tmp.mem.pre,tmp); cout<<"mem content:"<<buf+pcb_tmp.mem.pre<<endl; }else { cout<<"allocate mem error"<<endl; continue; } }else if(w==1) { //杀死进程,模拟内存回收 cout<<"input pid"<<endl; cin>>pcb_tmp.pid; cout<<"kill---"<<pcb_tmp.pid<<endl; list<PCB>::iterator it=pcb.begin(); //找到该pcb for( ;it!=pcb.end();it++) { if(it->pid==pcb_tmp.pid) { break; } } del(it->mem); pcb.erase(it); //free }else if(w==2) { //compact cout<<"compact"<<endl; compact(); }else break; show(); } //free all mems return 0; }
-
测试数据
input: 0 1 10 aaa 0 2 10 bbb 0 3 10 ccc 0 4 10 ddd 1 2 2 3 output: 测试内存浮动 status: pcb: mfree: mused: 0 1 0 ------------------------ create 0 pidnum or kill 1 pidnum or compact 2 or 3 exit create process ,input(pid,mem size,brief) 1 200-10 mem content:aaa status: pcb: mfree: mused: 1 1 1 ------------------------ create 0 pidnum or kill 1 pidnum or compact 2 or 3 exit create process ,input(pid,mem size,brief) 1 190-10 mem content:bbb status: pcb: mfree: mused: 2 1 2 ------------------------ create 0 pidnum or kill 1 pidnum or compact 2 or 3 exit create process ,input(pid,mem size,brief) 1 180-10 mem content:ccc status: pcb: mfree: mused: 3 1 3 ------------------------ create 0 pidnum or kill 1 pidnum or compact 2 or 3 exit create process ,input(pid,mem size,brief) 1 170-10 mem content:ddd status: pcb: mfree: mused: 4 1 4 ------------------------ create 0 pidnum or kill 1 pidnum or compact 2 or 3 exit input pid kill---2 mem del... merge type: insert status: pcb: mfree: mused: 3 2 3 ------------------------ create 0 pidnum or kill 1 pidnum or compact 2 or 3 exit compact compact before: a a a b b b c c c d d d compact after: a a a c c c d d d d d d status: pcb: mfree: mused: 3 1 3 ------------------------ create 0 pidnum or kill 1 pidnum or compact 2 or 3 exit