模拟linux的内存分配与回收
模拟linux的内存分配与回收
要求
通过深入理解内存分配管理的三种算法,定义相应的数据结构,编写具体代码。 充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣。
(1)掌握内存分配FF,BF,WF策略及实现的思路;
(2)掌握内存回收过程及实现思路;
(3)参考给出的代码思路,实现内存的申请、释放的管理程序,调试运行。
主要过程
实现
#include<stdio.h>
#include<stdlib.h>
#define PROCESS_NAME_LEN 32
#define MIN_SLICE 10
#define DEFAULT_MEM_SIZE 1048
#define DEFAULT_MEM_START 0
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
typedef struct free_block_struct{
int size;
int start_addr;
struct free_block_struct *next;
}free_block_type;
free_block_type *free_block;
typedef struct allocated_block_struct{
int pid;
int size;
int start_addr;
char process_name[PROCESS_NAME_LEN];
struct allocated_block_struct *next;
}allocated_block;
allocated_block *allocated_block_head=NULL;
int memory_size_setted=0;
int mem_size=DEFAULT_MEM_SIZE;
int pid=0;
int memory_algorithm=1;
free_block_type* init_free_block()
{
free_block_type* fb=(free_block_type*)malloc(sizeof(free_block_type));
if(fb==NULL) return NULL;
fb->size=mem_size;
fb->start_addr=DEFAULT_MEM_START;
fb->next=NULL;
return fb;
}
void display_menu()
{
printf("*****************************************************\n");
printf("1. set memory size(default=%d)\n",DEFAULT_MEM_SIZE);
printf("2. select memory allocation algorithm\n");
printf("3. new process\n");
printf("4. kill process\n");
printf("5. display memory usage\n");
printf("0. exit\n");
printf("*****************************************************\n");
}
int set_mem_size()
{
int size;
if(memory_size_setted)
{
printf("memory size has been setted.\n");
return 0;
}
printf("total memory size:");
scanf("%d",&size);
char c;while ((c = getchar()) != EOF && c != '\n');
if(size>0)
{
mem_size=size;
free_block->size=mem_size;
memory_size_setted=1;
return 1;
}
else
return 0;
}
void alg_sort1(int mode)//1 up,0 down
{
free_block_type *pre,*p,*np,*head;
pre=(free_block_type*)malloc(sizeof(free_block_type));
pre->next=free_block;// add head node
p=free_block;
int len=0;
while(p)
{
len++;
p=p->next;
}
p=free_block;
for(int i=0;i<len;i++)
{
int first=1;
for(int j=0;j<len-i-1;j++)
{
if(first==1)
{
head=pre;
first=0;
np=p->next;
}
if(mode)//down
{
if(p->size>np->size)
{
pre->next=np;
p->next=np->next;
np->next=p;
}
}
else
{
if(p->size<np->size)
{
pre->next=np;
p->next=np->next;
np->next=p;
}
}
pre=p;
p=np;
np=np->next;
}
pre=head;
}
free_block=pre->next;
}
void swap(int *a,int *b)
{
int t=*a; *a=*b; *b=t;
}
void alg_sort(int mode)//1 up,0 down
{
free_block_type *p,*np;
p=free_block;
int len=0;
while(p)
{
len++;
p=p->next;
}
for(int i=0;i<len;i++)
{
p=free_block;
for(int j=0;j<len-i-1;j++)
{
np=p->next;
if(mode)//down
{
if(p->size>np->size)
{
swap(&p->size,&np->size);
swap(&p->start_addr,&np->start_addr);
}
}
else
{
if(p->size<np->size)
{
swap(&p->size,&np->size);
swap(&p->start_addr,&np->start_addr);
}
}
p=np;
}
}
}
void rearrange_FF()
{
return;
}
void rearrange_BF()
{
alg_sort(1);
}
void rearrange_WF()
{
alg_sort(0);
}
void rearrange(int n)
{
switch(n)
{
case MA_FF:rearrange_FF();break;
case MA_BF:rearrange_BF();break;
case MA_WF:rearrange_WF();break;
}
}
void set_algorithm()
{
int algorithm;
printf("1. first fit\n");
printf("2. best fit\n");
printf("3. worst fit\n");
scanf("%d",&algorithm);
char c;while ((c = getchar()) != EOF && c != '\n');
if(algorithm>=1&&algorithm<=3)
{
rearrange(algorithm);
memory_algorithm=algorithm;
}
else
printf("choice out of range\n");
}
int allocate_mem(allocated_block *ab)
{
int request=ab->size;
free_block_type *p,*pre;
pre=NULL;
p=free_block;
int first=1;
while(p)
{
if(p->size>=request)
{
ab->start_addr=p->start_addr;
int rest=p->size-request;
if(rest<MIN_SLICE)
{
ab->size+=rest;
}
else
{
free_block_type *new_block=(free_block_type*)malloc(sizeof(free_block_type));
new_block->size=rest;
new_block->start_addr=p->start_addr+request;
new_block->next=p->next;
ab->next=NULL;
if(first)
free_block=new_block;
else
pre->next=new_block;
}
p->size-=ab->size;
rearrange(memory_algorithm);
// free(p);
// free(pre);
return 1;
}
first=0;
pre=p;
p=p->next;
}
return -1;
}
int new_process()
{
allocated_block *ab=(allocated_block*)malloc(sizeof(allocated_block));
if(ab==NULL) return -1;
ab->next=NULL;
pid++;
sprintf(ab->process_name,"process_%02d",pid);
ab->pid=pid;
printf("memory for %s:",ab->process_name);
int size,ret;
scanf("%d",&size);
char c;while ((c = getchar()) != EOF && c != '\n');
if(size<=0) return 0;
ab->size=size;
ret=allocate_mem(ab);
if(ret==1&&allocated_block_head==NULL)
{
allocated_block_head=ab;
return 1;
}
else if(ret==1)
{
ab->next=allocated_block_head;
allocated_block_head=ab;
return 1;
}
else
{
printf("allocated failed\n");
free(ab);
return -1;
}
}
allocated_block* find_process(int pid)
{
allocated_block *p;
p=allocated_block_head;
while(p)
{
if(p->pid==pid) return p;
p=p->next;
}
return NULL;
}
void free_mem(allocated_block *ab)
{
free_block_type *fbt=(free_block_type*)malloc(sizeof(free_block_type)),*p,*np;
fbt->size=ab->size;
fbt->start_addr=ab->start_addr;
fbt->next=NULL;
p=free_block;
while(p->next)
p=p->next;
if(p->start_addr+p->size==fbt->start_addr)
{
p->size+=fbt->size;
p->next=NULL;
}
else
p->next=fbt;
rearrange(2);
p=free_block;
while(p->next)
{
np=p->next;
if(p->start_addr+p->size==np->start_addr)
{
p->size=p->size+np->size;
p->next=np->next;
}
else
p=np;
}
rearrange(memory_algorithm);
}
void dispose(allocated_block *ab)
{
if(ab==allocated_block_head)
{
allocated_block_head=allocated_block_head->next;
free(ab);
return;
}
allocated_block *pre,*p;
pre=allocated_block_head;
p=allocated_block_head->next;
while(p!=ab)
{
pre=p;
p=p->next;
}
pre->next=p->next;
free(ab);
}
void kill_process()
{
allocated_block *ab;
int pid;
printf("kill process,pid:");
scanf("%d",&pid);
char c;while ((c = getchar()) != EOF && c != '\n');
ab=find_process(pid);
if(ab!=NULL)
{
free_mem(ab);
dispose(ab);
}
else
{
printf("wrong pid,try again\n");
}
}
void display_mem_usage()
{
free_block_type *fbt=free_block;
allocated_block *ab=allocated_block_head;
if(fbt==NULL) return;
printf("\n");
printf("free memory:\n");
printf("%20s %20s\n","start_addr","size");
while(fbt!=NULL)
{
if(fbt->size)
printf("%20d %20d\n",fbt->start_addr,fbt->size);
fbt=fbt->next;
}
printf("memory used:\n");
printf("%10s %20s %10s %10s\n","pid","process_name","start_addr","size");
while(ab!=NULL)
{
printf("%10d %20s %10d %10d\n",ab->pid,ab->process_name,ab->start_addr,ab->size);
ab=ab->next;
}
}
void do_exit()
{
free(allocated_block_head);
free(free_block);
printf("over\n");
}
int main()
{
char choice;
free_block=init_free_block();
while(1)
{
display_menu();
scanf("%c",&choice);
char c;while ((c = getchar()) != EOF && c != '\n');
switch(choice)
{
case '1': set_mem_size();break;
case '2': set_algorithm();break;
case '3': new_process();break;
case '4': kill_process();break;
case '5': display_mem_usage();break;
case '0': do_exit();exit(0);
default: break;
}
}
return 0;
}
结果
按如下过程测试
- 设定分配算法为FF
- 分配三个进程的内存大小为:100,200,300
- 然后删去pid2
- 设定分配算法为WF
- 分配pid4大小为200,观察是否从满足要求的最小块划分
- 删去pid4,选择分配算法BF
- 分配pid5大小为200,观察是否满足最优分配
- 删去pid3,观察能否合并
- 删去pid1,分配pid6大小为99,观察如何处理碎片
- 退出
输出过长,省略
模拟linux的内存分配与回收的更多相关文章
- Java深入 - Java 内存分配和回收机制
Java的GC机制是自动进行的,和c语言有些区别需要程序员自己保证内存的使用和回收. Java的内存分配和回收也主要在Java的堆上进行的,Java的堆中存储了大量的对象实例,所以Java的堆也叫GC ...
- Java深入 - Java 内存分配和回收机制-转
Java的GC机制是自动进行的,和c语言有些区别需要程序员自己保证内存的使用和回收. Java的内存分配和回收也主要在Java的堆上进行的,Java的堆中存储了大量的对象实例,所以Java的堆也叫GC ...
- 图片系列(6)不同版本上 Bitmap 内存分配与回收原理对比
请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · AndroidFamily 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭锐] ...
- Java 对象内存分配与回收
JVM内存区域模型: * 程序计数器,内存区域极小,是当前线程的字节码执行行号指示器: * 虚拟机栈.本地方法栈,即平时所说的“栈”,是虚拟机用来执行方法(包括Java.非Java方法)时,使用的临时 ...
- 最简单例子图解JVM内存分配和回收
一.简介 JVM采用分代垃圾回收.在JVM的内存空间中把堆空间分为年老代和年轻代.将大量(据说是90%以上)创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象.年轻代中又被分 ...
- memcached内存分配及回收初探
对memcached(后面简称mc) 的内存分配及回收机制进行了深度分析和测试,以下是一些学习的心得,和大家共同探讨一下,期望能抛砖引玉 mc简介: mc是由LiveJournal技术团队开发的一套分 ...
- java虚拟机的内存分配与回收机制
分为4个方面来介绍内存分配与回收,分别是内存是如何分配的.哪些内存需要回收.在什么情况下执行回收.如何监控和优化GC机制. java GC(Garbage Collction)垃圾回收机制,是java ...
- Android的内存分配与回收
想写一篇关于android的内存分配和回收文章的想法来源于追查一个魅族手机图片滑动卡顿问题,我们想了很多办法还是没有避免他不停的GC,所以就打算详细的看看内存分配和GC的原理,为什么会不断的GC,GC ...
- Java虚拟机垃圾回收:内存分配与回收策略 方法区垃圾回收 以及 JVM垃圾回收的调优方法
在<Java对象在Java虚拟机中的创建过程>了解到对象创建的内存分配,在<Java内存区域 JVM运行时数据区>中了解到各数据区有些什么特点.以及相关参数的调整,在<J ...
随机推荐
- linux简单介绍,helloworld,vi使用,用户管理
linux特点1.免费的.开源的2.支持多线程.多用户的3.安全性好4.对内存和文件管理优越 缺点:操作相对困难 linux最小只需要4m -> 嵌入式开发 我们使用 vm[虚拟机] 虚拟了一个 ...
- 对servlet的 再总结 (精品)
首先 可以通过URL 在浏览器端访问servlet,因为在web.xml中配置了URL与类全名的 映射. 我们初学时,很容易分不清,浏览器端访问的 是jsp页面还是servlet. 其实当我们用浏览 ...
- 发现的好东西——bitset
先向各位大佬介绍一个水题 任何一个正整数都可以用2的幂次方表示.例如 137=2^7+2^3+2^0 同时约定方次用括号来表示,即a^b 可表示为a(b). 由此可知,137可表示为: 2(7)+2( ...
- flowable 6.1.2 命令行完成请假审批流程的例子
一.创建 eclipse maven新项目 1.设置项目选项 其中,Create a simple project 要选中. 2.填写项目包名和项目名称 这里的Group id:必须是 org.flo ...
- 循环神经网络RNN模型和长短时记忆系统LSTM
传统DNN或者CNN无法对时间序列上的变化进行建模,即当前的预测只跟当前的输入样本相关,无法建立在时间或者先后顺序上出现在当前样本之前或者之后的样本之间的联系.实际的很多场景中,样本出现的时间顺序非常 ...
- 首次尝试LINUX下的ssh命令:登录和退出
1:我现在本机安装了centos虚拟机,然后在windows桌面下使用SecureCRT ssh客户端登录我的本地虚拟机,再然后 通过centos下的ssh命令登录局域网内测试机192.168.0.1 ...
- 剑指offer-第六章面试中的各项能力(数组中只出现一次的数字)
题目:输入一个数组,该数组中有两个只出现一次的数字,其他的数字都出现两次,输出出只出现一次的数字. 思路:首先,我们可以将这个数组分成两份,一份里面放一个只出现一次的数字.那么我们该怎么分呢?将整个数 ...
- LG4360 [CEOI2004]锯木厂选址
题意 原题来自:CEOI 2004 从山顶上到山底下沿着一条直线种植了 n 棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂. 木材只能朝山下运.山脚下有一个锯木厂 ...
- 前端工程师面试问题归纳(一、问答类html/css/js基础)
一.参考资源 1.前端面试题及答案整理(一) 2.2017年前端面试题整理汇总100题 3.2018最新Web前端经典面试试题及答案 4.[javascript常见面试题]常见前端面试题及答案 5.W ...
- Markdown编辑器推荐与语法教程--展示版
---恢复内容开始--- 前言 作为一名高级码农,怎能不知道Markdown的正确打开方式,Markdown现在可以说是无处不在,如果你还不知道简书中的代码块是怎么写出来的,小白无疑了.在此特别推荐一 ...