Java教程

内存管理模拟

本文主要是介绍内存管理模拟,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

实验三. 内存管理

二、实验内容

​ 假定页面大小为4K,物理内存128M,设计并实现一个内存分配和回收的程序,使用C语言或Python语言编写程序实现这个程序并进行测试。
​ 要求:(1)至少5个进程;
​ (2)要求有空块管理;
​ (3)要求有一个逻辑地址到物理地址的变换。

四、程序代码

4.1 代码主要思想及设计原理
1. 在main函数中调用内存分配, 地址使用(包含地址转换) , 内存释放函数.
2. 在全局变量中有基本的页大小和内存大小定义,也有进程类的定义和进程队列的定义.
3. init初始化函数为根据输入的进程数创建需要随机数个大小的内存,然后计算分配页面.(随机数服从一个高斯函数),也包含随机初始化页的占用情况.
4. 内存分配使用最先适应算法,即在位视图中查找,找到空块就填入,占用.
5. 内存释放,直接释放资源,修改位视图.
4.2 程序代码
#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;
}

五、运行结果

多次测试的结果:

在这里插入图片描述在这里插入图片描述在这里插入图片描述

六、结果分析

  1. 由结果可以直观看出,进程创建正确,随机产生需要的内存大小,并计算需要的页数; 然后进行块分配,写入页表. 然后进程按需访问内存, 最后使用完成释放.
这篇关于内存管理模拟的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!