OS 内存管理

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
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值