假定页面大小为4K,物理内存128M,设计并实现一个内存分配和回收的程序,使用C语言或Python语言编写程序实现这个程序并进行测试。
要求:(1)至少5个进程;
(2)要求有空块管理;
(3)要求有一个逻辑地址到物理地址的变换。
1. 在main函数中调用内存分配, 地址使用(包含地址转换) , 内存释放函数. 2. 在全局变量中有基本的页大小和内存大小定义,也有进程类的定义和进程队列的定义. 3. init初始化函数为根据输入的进程数创建需要随机数个大小的内存,然后计算分配页面.(随机数服从一个高斯函数),也包含随机初始化页的占用情况. 4. 内存分配使用最先适应算法,即在位视图中查找,找到空块就填入,占用. 5. 内存释放,直接释放资源,修改位视图.
#include <iostream> #include <random> #include <chrono> #include <cmath> #define PAGESIZE 4000 #define MEMORYSIZE 128000000 using namespace std; int bitview[32000];//页的位视图,1表示被占用 int freeBlocksCount; class process { public: int pid; int needmemory; int needpage; int pagetable[128]; }; int psum; process p[128];//进程总数量在这里修改 void createProcess(int psum); void initBitView(){ unsigned seed = chrono::system_clock::now().time_since_epoch().count(); default_random_engine generator(seed); // 第一个参数为高斯分布的平均值,第二个参数为标准差 std::normal_distribution<double> distribution(0.0, 15.0 * PAGESIZE); int t; for(int i=0;i<32000;i++){ t=abs((int)distribution(generator)); t=t%2; bitview[i]=t; } } void init() { cout << "请输入进程数量:" << endl; cin >> psum; createProcess(psum); initBitView(); cout<<"已经随机初始化内存块的占用情况" <<endl; // for(int i=0;i<100;i++){ // cout << bitview[i]<<" " <<ends; // } } void createProcess(int psum) { // 从epoch(1970年1月1日00:00:00 UTC)开始经过的纳秒数,unsigned类型会截断这个值 unsigned seed = chrono::system_clock::now().time_since_epoch().count(); default_random_engine generator(seed); // 第一个参数为高斯分布的平均值,第二个参数为标准差 std::normal_distribution<double> distribution(0.0, 15.0 * PAGESIZE); cout <<"进程号|"<<"需要的总内存|"<<" 计算后需要的块数|" <<endl; for (int i = 0; i < psum; i++) { process p1; p1.pid=i; p1.needmemory = abs((int)distribution(generator)); p1.needpage = p1.needmemory / PAGESIZE ; if(p1.needmemory%PAGESIZE)p1.needpage++; cout <<i<<" : " << p1.needmemory <<" " <<p1.needpage<<endl; p[i]=p1; } } void memAlocation(){ int bitviewpoint=0; for(int i=0;i<psum;i++){ cout << "\n进程"<<p[i].pid<< "已分配" <<p[i].needpage <<"页. 分配的页号为:"<<endl; for(int j=0;j<p[i].needpage;j++){ while(bitview[bitviewpoint]==1)bitviewpoint++; bitview[bitviewpoint]=1; p[i].pagetable[j]=bitviewpoint; cout <<bitviewpoint <<" " <<ends; } } } int addrTranslate(int plot,int addrInPage){ return plot+addrInPage; } void addrAccess(){ // 从epoch(1970年1月1日00:00:00 UTC)开始经过的纳秒数,unsigned类型会截断这个值 unsigned seed = chrono::system_clock::now().time_since_epoch().count(); default_random_engine generator(seed); // 第一个参数为高斯分布的平均值,第二个参数为标准差 std::normal_distribution<double> distribution(0.0, 15.0 * PAGESIZE); int t=abs((int)distribution(generator)); for(int i=0;i<t%25;i++){ int pRandom=abs((int)distribution(generator)); pRandom=pRandom%psum; int randn=abs((int)distribution(generator)); randn=randn%4000; cout <<"进程"<<p[pRandom].pid<<"访问了"<<p[pRandom].pagetable[1]<<"页的地址,地址为:"<< addrTranslate((p[pRandom].pagetable[1]) *4000, randn)<< endl; } } void memRecover (){//内存回收 for(int i=0;i<psum;i++){ for(int j=0;j<p[i].needpage;j++){ bitview[p[i].pagetable[j]]=0; } cout <<"进程" << p[i].pid <<"共释放了" <<p[i].needpage <<"页. "<<endl; } } int main() { init(); memAlocation(); addrAccess(); memRecover(); return 0; }
多次测试的结果: