内存分配---FF、BF、WF三种算法
动态分区分配是根据进程的实际需要,动态的为之分配内存空间。而在实现可变分区分配时,将涉及到分区分配中
所用的数据结构、分区分配算法和分区的分配与内存回收的过程。
分区分配中的数据结构:(1)描述空闲块的数据结构。(2)内存块的描述。
#define PROCESS_NAME_LEN 32 //进程名长度
#define MIN_SLICE 10 //最小碎片的大小
#define DEFAULT_MEM_SIZE 1024 //内存大小
#define DEFAULT_MEM_START 0 //起始位置
//内存分配算法
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
//描述每一个空闲块的数据结构
struct free_block_type
{
int size; //空闲块大小
int start_addr; //空闲块起始位置
struct free_block_type *next; //指向下一个空闲块
};
//指向内存中空闲块链表的首地址
struct free_block_type *free_block= NULL;
//每个进程分配到的内存块的描述
struct allocated_block
{
int pid;
int size; //进程大小
int start_addr; //进程分配到的内存块的起始地址
char process_name[PROCESS_NAME_LEN]; //进程名
struct allocated_block *next; //指向下一个进程控制块
};
//进程分配内存块链表的首指针
struct allocated_block *allocated_block_head= NULL;
int free_block_count= ; //空闲块的个数
int mem_size= DEFAULT_MEM_SIZE; //内存大小
int current_free_mem_size= ; //当前空闲内存大小
int ma_algorithm= MA_FF; //当前分配算法
static int pid= ;
int flag= ; //设置内存大小标志,表示内存大小是否设置
分区分配算法:
(1)首次适应算法(First Fit):从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给
作业,这种方法的目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到
高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。
(2)最佳适应算法(Best Fit):从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使
碎片尽量小。为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一
个满足要求的自由分区分配。该算法保留大的空闲区,但造成许多小的空闲区。
(3)最差适应算法(Worst Fit):从全部空闲区中找出能满足作业要求的、且大小最大的空闲分区,从而使链表中
的结点大小趋于均匀,适用于请求分配的内存大小范围较窄的系统。为适应此算法,空闲分区表(空闲区链)中的空
闲分区按大小从大到小进行排序,自表头开始查找到第一个满足要求的自由分区分配。该算法保留小的空闲区,尽量
减少小的碎片产生。
下面是进行以上三种算法的实现:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <unistd.h> #define PROCESS_NAME_LEN 32 //进程名长度
#define MIN_SLICE 10 //最小碎片的大小
#define DEFAULT_MEM_SIZE 1024 //内存大小
#define DEFAULT_MEM_START 0 //起始位置
//内存分配算法
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
//描述每一个空闲块的数据结构
struct free_block_type
{
int size; //空闲块大小
int start_addr; //空闲块起始位置
struct free_block_type *next; //指向下一个空闲块
};
//指向内存中空闲块链表的首地址
struct free_block_type *free_block= NULL;
//每个进程分配到的内存块的描述
struct allocated_block
{
int pid;
int size; //进程大小
int start_addr; //进程分配到的内存块的起始地址
char process_name[PROCESS_NAME_LEN]; //进程名
struct allocated_block *next; //指向下一个进程控制块
};
//进程分配内存块链表的首指针
struct allocated_block *allocated_block_head= NULL;
int free_block_count= ; //空闲块的个数
int mem_size= DEFAULT_MEM_SIZE; //内存大小
int current_free_mem_size= ; //当前空闲内存大小
int ma_algorithm= MA_FF; //当前分配算法
static int pid= ;
int flag= ; //设置内存大小标志,表示内存大小是否设置 struct free_block_type* init_free_block(int mem_size);
void display_menu();
int set_mem_size();
void set_algorithm();
void rearrange(int algorithm);
int rearrange_WF();
int rearrange_BF();
int rearrange_FF();
int new_process();
int allocate_mem(struct allocated_block *ab);
void kill_process();
int free_mem(struct allocated_block *ab);
int dispose(struct allocated_block *free_ab);
int display_mem_usage();
struct allocated_block* find_process(int pid);
int do_exit();
int allocate_FF(struct allocated_block *ab);
int allocate_BF(struct allocated_block *ab);
int allocate_WF(struct allocated_block *ab);
int allocate(struct free_block_type *pre,struct free_block_type *allocate_free_nlock,struct allocated_block *ab);
int mem_retrench(struct allocated_block *ab); //通过内存紧缩技术给新进程分配内存空间
int mem_retrench(struct allocated_block *ab)
{
struct allocated_block *allocated_work,*allocated_pre= allocated_block_head;
struct free_block_type *free_work,*free_pre= free_block->next;
if(allocated_pre== NULL)
return -;
allocated_pre->start_addr= ;
allocated_work= allocated_pre->next;
while(allocated_work!= NULL)
{
allocated_work->start_addr= allocated_pre->start_addr+ allocated_pre->size;
allocated_pre= allocated_work;
allocated_work= allocated_work->next;
}
free_block->start_addr= allocated_pre->start_addr+ allocated_pre->size;
free_block->size= current_free_mem_size;
free_work= free_pre;
while(free_pre!= NULL)
{
free(free_pre);
free_pre= free_work;
if(free_pre!= NULL)
free_work= free_work->next;
}
allocate(NULL,free_block,ab);
return ;
} //给新进程分配内存空间
int allocate(struct free_block_type *pre,struct free_block_type *allocate_free_block,struct allocated_block *ab)
{
struct allocated_block *p= allocated_block_head;
ab->start_addr= allocate_free_block->start_addr;
if(allocate_free_block->size-ab->size< MIN_SLICE)
{
ab->size= allocate_free_block->size;
if(pre!= NULL)
{
pre->next= allocate_free_block;
}
else
{
free_block= allocate_free_block->next;
}
free(allocate_free_block);
}
else
{
allocate_free_block->start_addr+= ab->size;
allocate_free_block->size-= ab->size;
}
if(p== NULL)
{
allocated_block_head= ab;
}
else
{
while(p->next!= NULL)
p= p->next;
p->next= ab;
}
current_free_mem_size-= ab->size;
if(current_free_mem_size== )
free_block= NULL;
return ;
} //按照最坏适应算法给新进程分配内存空间
int allocate_WF(struct allocated_block *ab)
{
int ret;
struct free_block_type *wf= free_block;
if(wf== NULL)
return -;
if(wf->size>= ab->size)
allocate(NULL,wf,ab);
else if(current_free_mem_size>= ab->size)
ret= mem_retrench(ab);
else
ret= -;
rearrange_WF();
return ret;
} //按照最佳适应算法给新进程分配内存空间
int allocate_BF(struct allocated_block *ab)
{
int ret;
struct free_block_type *pre= NULL,*bf= free_block;
if(bf== NULL)
return -;
while(bf!= NULL)
{
if(bf->size>= ab->size)
{
ret= allocate(pre,bf,ab);
break;
}
pre= bf;
pre= pre->next;
}
if(bf== NULL&¤t_free_mem_size> ab->size)
ret= mem_retrench(ab);
else
ret= -;
rearrange_BF();
return ret;
} //按照首次适应算法给新进程分配内存空间
int allocate_FF(struct allocated_block *ab)
{
int ret;
struct free_block_type *pre= NULL,*ff= free_block;
if(ff== NULL)
return -;
while(ff!= NULL)
{
if(ff->size>= ab->size)
{
ret= allocate(pre,ff,ab);
break;
}
pre= ff;
pre= pre->next;
}
if(ff== NULL&¤t_free_mem_size> ab->size)
ret= mem_retrench(ab);
else
ret= -;
rearrange_FF();
return ret;
} //分配内存模块
int allocate_mem(struct allocated_block *ab)
{
int ret;
struct free_block_type *fbt,*pre;
int request_size= ab->size;
fbt= pre= free_block;
switch(ma_algorithm)
{
case MA_FF:
ret= allocate_FF(ab);
break;
case MA_BF:
ret= allocate_BF(ab);
break;
case MA_WF:
ret= allocate_WF(ab);
break;
default:
break;
}
return ret;
} //创建一个新进程
int new_process()
{
struct allocated_block *ab;
int size;
int ret;
ab= (struct allocated_block*)malloc(sizeof(struct allocated_block));
if(!ab)
exit(-);
ab->next= NULL;
pid++;
sprintf(ab->process_name,"PROCESS-%02d",pid);//将格式化的数据写入某字符串中
ab->pid= pid;
printf("Memory for %s:",ab->process_name);
for(;;)
{
scanf("%d",&size);
getchar();
if(size> )
{
ab->size= size;
break;
}
else
printf("The size have to greater than zero!Please input again!");
}
ret= allocate_mem(ab);
if((ret== )&&(allocated_block_head== NULL)) //如果此时未赋值,则赋值
{
allocated_block_head= ab;
return ;
}
else if(ret== ) //分配成功,将该已分配块的描述插入已分配链表
{
ab->next= allocated_block_head;
allocated_block_head= ab;
return ;
}
else if(ret== -) //分配不成功
{
printf("Allocation fail.\n");
free(ab);
return -;
}
return ;
} //退出程序并释放空间
int do_exit()
{
struct allocated_block *allocated_ab,*allocated_pre;
struct free_block_type *free_ab,*free_pre;
free_pre= free_block;
allocated_pre= allocated_block_head;
if(free_pre!= NULL)
{
free_ab= free_pre->next;
while(free_ab!= NULL)
{
free(free_pre);
free_pre= free_ab;
free_ab= free_ab->next;
}
}
if(allocated_pre!= NULL)
{
allocated_ab= allocated_pre->next;
while(allocated_ab!= NULL)
{
free(allocated_pre);
allocated_pre= allocated_ab;
allocated_ab= allocated_ab->next;
}
}
allocated_ab= allocated_ab->next;
return ;
} //在进程分配链表中寻找指定进程
struct allocated_block* find_process(int pid)
{
struct allocated_block *ab= allocated_block_head;
if(ab== NULL)
{
printf("Here?111\n");
return NULL;
}
while(ab->pid!= pid&&ab->next!= NULL)
ab= ab->next;
if(ab->next== NULL&&ab->pid!= pid)
{
printf("Here?222\n");
return NULL;
}
return ab;
} //显示当前内存的使用情况,包括空闲区的情况和已经分配的情况
int display_mem_usage()
{
struct free_block_type *fbt= free_block;
struct allocated_block *ab= allocated_block_head;
printf("-------------------------------------------------------------\n");
printf("Free Memory:\n");
printf("%20s %20s\n"," start_addr"," size");
while(fbt!= NULL)
{
printf("%20d %20d\n",fbt->start_addr,fbt->size);
fbt= fbt->next;
}
printf("\nUsed Memory:\n");
printf("%10s %20s %10s %10s\n","PID","ProcessName","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;
}
printf("-------------------------------------------------------------\n");
return ;
} //释放ab数据结构结点
int dispose(struct allocated_block *free_ab)
{
struct allocated_block *pre,*ab;
if(free_block== NULL)
return -;
if(free_ab== allocated_block_head) //如果要释放第一个结点
{
allocated_block_head= allocated_block_head->next;
free(free_ab);
}
else
{
pre= allocated_block_head;
ab= allocated_block_head->next;
//找到free_ab
while(ab!= free_ab)
{
pre= ab;
ab= ab->next;
}
pre->next= ab->next;
free(ab);
}
return ;
} //将ab所表示的已分配区归还,并进行可能的合并
int free_mem(struct allocated_block *ab)
{
int algorithm= ma_algorithm;
struct free_block_type *fbt,*pre,*work;
fbt= (struct free_block_type*)malloc(sizeof(struct free_block_type));
if(!fbt)
return -;
pre= free_block;
fbt->start_addr= ab->start_addr;
fbt->size= ab->size;
fbt->next= NULL;
if(pre!= NULL)
{
while(pre->next!= NULL)
pre= pre->next;
pre->next= fbt;
}
else
{
free_block= fbt;
}
rearrange_FF();
pre= free_block;
work= pre->next;
while(work!= NULL)
{
if(pre->start_addr+ pre->size== work->start_addr)
{
pre->size+= work->size;
free(work);
work= pre->next;
}
else
{
pre= work;
work= work->next;
}
}
current_free_mem_size+= ab->size;
return ;
} //删除进程,归还分配的存储空间,并删除描述该进程内存分配的结点
void kill_process()
{
struct allocated_block *ab;
int pid;
printf("Kill Process,pid=");
scanf("%d",&pid);
getchar();
ab= find_process(pid);
if(ab!= NULL)
{
free_mem(ab); //释放ab所表示的分配区
dispose(ab); //释放ab数据结构结点
}
} //按FF算法重新整理内存空闲块链表,按空闲块首地址排序
int rearrange_FF()
{
struct free_block_type *head= free_block;
struct free_block_type *forehand,*pre,*rear;
int i;
if(head== NULL)
return -;
for(i= ;i< free_block_count-;i++)
{
forehand= head;
pre= forehand->next;
rear= pre->next;
while(pre->next!= NULL)
{
if(forehand== head&&forehand->start_addr>= pre->start_addr)
{
//比较空闲链表中第一个空闲块与第二个空闲块的开始地址的大小
head->next= pre->next;
pre->next= head;
head= pre;
forehand= head->next;
pre= forehand->next;
rear= pre->next;
}
else if(pre->start_addr>= rear->start_addr)
{
//比较链表中其它相邻两个结点的开始地址的大小
pre->next= rear->next;
forehand->next= rear;
rear->next= pre;
forehand= rear;
rear= pre->next;
}
else
{
forehand= pre;
pre= rear;
rear= rear->next;
}
}
}
return ;
} //按BF算法重新整理内存空闲块链表,按空闲块大小从小到大排序
int rearrange_BF()
{
struct free_block_type *head= free_block;
struct free_block_type *forehand,*pre,*rear;
int i;
if(head== NULL)
return -;
for(i= ;i< free_block_count-;i++)
{
forehand= head;
pre= forehand->next;
rear= pre->next;
while(pre->next!= NULL)
{
if(forehand== head&&forehand->size<= pre->size)
{
//比较空闲链表中第一个空闲块与第二个空闲块的空间的大小
head->next= pre->next;
pre->next= head;
head= pre;
forehand= head->next;
pre= forehand->next;
rear= pre->next;
}
else if(pre->size<= rear->size)
{
//比较链表中其它相邻两个结点的空间的大小
pre->next= rear->next;
forehand->next= rear;
rear->next= pre;
forehand= rear;
rear= pre->next;
}
else
{
forehand= pre;
pre= rear;
rear= rear->next;
}
}
}
return ;
} //按WF算法重新整理内存空闲块链表,按空闲块大小从大到小排序
int rearrange_WF()
{
struct free_block_type *head= free_block;
struct free_block_type *forehand,*pre,*rear;
int i;
if(head== NULL)
return -;
for(i= ;i< free_block_count-;i++)
{
forehand= head;
pre= forehand->next;
rear= pre->next;
while(pre->next!= NULL)
{
if(forehand== head&&forehand->size>= pre->size)
{
//比较空闲链表中第一个空闲块与第二个空闲块空间的大小
head->next= pre->next;
pre->next= head;
head= pre;
forehand= head->next;
pre= forehand->next;
rear= pre->next;
}
else if(pre->size>= rear->size)
{
//比较链表中其它相邻两个结点的空间的大小
pre->next= rear->next;
forehand->next= rear;
rear->next= pre;
forehand= rear;
rear= pre->next;
}
else
{
forehand= pre;
pre= rear;
rear= rear->next;
}
}
}
return ;
} //按指定的算法整理内存空闲块链表
void rearrange(int algorithm)
{
switch(algorithm)
{
case MA_FF:
rearrange_FF();
break;
case MA_BF:
rearrange_BF();
break;
case MA_WF:
rearrange_WF();
break;
}
} //设置当前的分配算法
void set_algorithm()
{
int algorithm;
//system("clear");
printf("\t1-First Fit\n"); //首次适应算法
printf("\t2-Best Fit\n"); //最佳适应算法
printf("\t3-Worst Fit\n"); //最坏适应算法
printf("Please choose(1-3):");
for(;;)
{
scanf("%d",&algorithm);
getchar();
if(algorithm>= &&algorithm<= )
{
ma_algorithm= algorithm;
break;
}
else
{
printf("\nCannot input %d,Please input 1-3:",algorithm);
}
}
rearrange(ma_algorithm);
} //设置内存的大小
int set_mem_size()
{
int size;
if(flag!= ) //防止重复设置
{
printf("Cannont set memory size again\n");
return ;
}
printf("Total memory size=");
for(;;)
{
scanf("%d",&size);
getchar();
if(size> )
{
current_free_mem_size= size;
mem_size= size;
free_block->size= mem_size;
break;
}
else
{
printf("The size must greater than zero!Please input again:");
}
}
flag= ; //内存大小已经设置
return ;
} //显示主菜单
void display_menu()
{
printf("\n");
//system("clear");
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-Terminate a process\n");
printf("5-Display memory usage\n");
printf("0-Exit\n");
} //初始化空闲块,默认为一块,可以指定大小及起始地址
struct free_block_type* init_free_block(int mem_size)
{
struct free_block_type *fb;
fb= (struct free_block_type*)malloc(sizeof(struct free_block_type));
if(fb== NULL)
{
printf("No mem\n");
return NULL;
}
current_free_mem_size= mem_size;
fb->size= mem_size;
fb->start_addr= DEFAULT_MEM_START;
fb->next= NULL; //首地址指向NULL
return fb;
} int main()
{
char choice;
pid= ;
free_block= init_free_block(mem_size);
while()
{
display_menu();
fflush(stdin);
choice= getchar();
getchar();
switch(choice)
{
case '': //设置内存大小
set_mem_size();
break;
case '': //设置算法
set_algorithm();
flag= ;
break;
case '': //创建新进程
new_process();
flag= ;
break;
case '': //删除进程
kill_process();
flag= ;
break;
case '': //显示内存使用
display_mem_usage();
flag= ;
break;
case '': //释放链表并退出
do_exit();
exit();
default:
break;
}
}
}
内存分配---FF、BF、WF三种算法的更多相关文章
- 浅析C++内存分配与释放操作过程——三种方式可以分配内存new operator, operator new,placement new
引言:C++中总共有三种方式可以分配内存,new operator, operator new,placement new. 一,new operator 这就是我们最常使用的 new 操作符.查看汇 ...
- Java利用DES/3DES/AES这三种算法分别实现对称加密
转载地址:http://blog.csdn.net/smartbetter/article/details/54017759 有两句话是这么说的: 1)算法和数据结构就是编程的一个重要部分,你若失掉了 ...
- 最短路问题的三种算法&模板
最短路算法&模板 最短路问题是图论的基础问题.本篇随笔就图论中最短路问题进行剖析,讲解常用的三种最短路算法:Floyd算法.Dijkstra算法及SPFA算法,并给出三种算法的模板.流畅阅读本 ...
- c语言求回文数的三种算法的描述
c语言求回文数的三种算法的描述 题目描述 注意:(这些回文数都没有前导0) 1位的回文数有0,1,2,3,4,5,6,7,8,9 共10个: 2位的回文数有11,22,33,44,55,66,77,8 ...
- git merge --ff/--no-ff/--ff-only 三种选项参数的区别
前言 git merge 应该是开发者最常用的 git 指令之一, 默认情况下你直接使用 git merge 命令,没有附加任何选项命令的话,那么应该是交给 git 来判断使用哪种 merge 模式, ...
- JVM内存分配策略,及垃圾回收算法
本人免费整理了Java高级资料,一共30G,需要自己领取;传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 说起垃圾收集(Garbage Co ...
- 图文实例解析,InnoDB 存储引擎中行锁的三种算法
前文提到,对于 InnoDB 来说,随时都可以加锁(关于加锁的 SQL 语句这里就不说了,忘记的小伙伴可以翻一下上篇文章),但是并非随时都可以解锁.具体来说,InnoDB 采用的是两阶段锁定协议(tw ...
- 缓存算法(FIFO 、LRU、LFU三种算法的区别)
FIFO算法 FIFO 算法是一种比较容易实现的算法.它的思想是先进先出(FIFO,队列),这是最简单.最公平的一种思想,即如果一个数据是最先进入的,那么可以认为在将来它被访问的可能性很小.空间满的时 ...
- 常见算法:C语言求最小公倍数和最大公约数三种算法
最小公倍数:数论中的一种概念,两个整数公有的倍数成为他们的公倍数,当中一个最小的公倍数是他们的最小公倍数,相同地,若干个整数公有的倍数中最小的正整数称为它们的最小公倍数,维基百科:定义点击打开链接 求 ...
随机推荐
- 【实用类String】String类方法的应用案例:查找判断指定字符出现的次数和位置
一.应用要求 输入一个字符串,再输入要查找的字符,判断该字符在该字符串中出现的次数. 二.实现思路 1.使用substring()方法将字符串的每个字符存入数组 2.比较数组每个字符是否与指定的字符相 ...
- 深入理解java线程池—ThreadPoolExecutor
几句闲扯:首先,我想说java的线程池真的是很绕,以前一直都感觉新建几个线程一直不退出到底是怎么实现的,也就有了后来学习ThreadPoolExecutor源码.学习源码的过程中,最恶心的其实就是几种 ...
- 前端之CSS——盒子模型和浮动
一.CSS盒子模型 HTML文档中的每个元素都被描绘成矩形盒子,这些矩形盒子通过一个模型来描述其占用空间,这个模型称为盒子模型. 盒子模型通过四个边界来描述:margin(外边距),border(边框 ...
- 从零开始的全栈工程师——ajax
AJAX AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. AJAX = Asynchronous JavaScript and XML. AJAX 是一种用于创建快速动态网页 ...
- iOS Touch ID 简易开发教程
转自:NsstringFromName 支持系统和机型 iOS系统的指纹识别功能最低支持的机型为iPhone 5s,最低支持系统为iOS 8,虽然安装iOS 7系统的5s机型可以使用系统提供的指纹解锁 ...
- centos的nginx支持ssl
首先看centos是否支持ssl 输入:openssl version 如无 则去 http://slproweb.com/products/Win32OpenSSL.html 寻找 生成私钥后面的 ...
- Zygote和System进程的启动过程
##init脚本的启动 +------------+ +-------+ +-----------+ |Linux Kernel+--> |init.rc+-> |app_process| ...
- html表格设置
表格 表格由 <table> 标签来定义.每个表格均有若干行(由 <tr> 标签定义),每行被分割为若干单元格(由 <td> 标签定义).字母 td 指表格数据(t ...
- ASP.NET向MySQL写入中文的乱码问题-.NET技术/C#
1,在 mysql数据库安装目录下找到my.ini文件,把default-character-set的值修改为 default-character-set=gb2312(修改两处),保存,重新启动. ...
- Python 列表(list)操作
创建列表 sample_list = ['a',1,('a','b')] Python 列表操作 sample_list = ['a','b',0,1,3] 得到列表中的某一个值 value_star ...