您的位置:首页 > 其它

操作系统实验二——内存平均利用率与分配策略的研究

2006-05-22 12:10 399 查看
参考windows任务管理器中内存占用的情况,在256M的总内存中,各个进程所占的内存从几十K到几十M不等,基本可以看成是均匀分布。即,每个进程申请使用的内存占总内存的百分比比较接近实际的数据为从千分之几到百分之十几,在这里,我们取从0.02%到15%。

但是为了说明情况,在实验中,我将申请内存占总内存的比率分为六个区间,分别为:0.02%——2%,0.02%——8%,0.02%——15%,0.02%——25%,0.02%——40%,0.02%——60%。对于四种不同的分配策略,分别考察从区间0.02%——2%变化到0.02%——60%时内存平均利用率的变化情况。可以得出较一般的结论。

实验结果如下:



将实验结果用图示的方法表现出来如下图所示:



从这张内存分配策略实验比较图可以看出,总体来说,仅就内存平均利用率这一个指标来看,best-fit > first-fit > next-fit > worst-fit。且随着申请内存占总内存比率的增大,各种分配策略的内存平均利用率趋于一致。从各种分配策略单独来看,随着申请内存占总内存比率的增大,各种分配策略的内存平均利用率都有所下降,但下降的速率有所差别。相比较而言,平均利用率最大的best-fit下降的幅度最大,而平均利用率最小的worst-fit下降的幅度最小,first-fit和next-fit居于它们之间。

总体结论:内存平均利用率的好坏不仅和内存的分配策略有关,还和进程申请内存占总内存的平均比率有关。在同等条件下,若仅考虑内存分配策略,则best-fit > first-fit > next-fit > worst-fit,若仅考虑申请内存占总内存的比率,则随着申请内存占总内存比率的增大,内存平均使用率下降,下降的斜率best-fit > first-fit > next-fit > worst-fit。

附:

对程序的一点说明:

程序中,用两个数据结构来维护内存使用状况,分别是USED_LINK和FREE_LINK。链表中的每一项都是一个BLOCK_NODE,其定义为:

typedef struct block{
//int blockId;
int startPosition;
int endPosition;
int length;
struct block *next;
} BLOCK_NODE, *pBLOCK_NODE;

程序中,模拟内存的大小为256M,即

#define MEM_SIZE 268435456 //256M

内存初始化,申请内存以及释放内存的函数分别定义为:

void mem_init();

int mem_request(int size, STRATEGY strategy);

bool mem_release(int startPosition);

其中,STRATEGY对应于四种不同的分配策略:

typedef enum {FIRST_FIT, NEXT_FIT, BEST_FIT, WORST_FIT} STRATEGY;

完整的源代码如下:

mem.h

#ifndef _MEM_H
#define _MEM_H

#include <stdio.h>

//#define MEM_SIZE 1024 //1K
//#define MEM_SIZE 1048576 //1M
#define MEM_SIZE 268435456 //256M

typedef struct block{
//int blockId;
int startPosition;
int endPosition;
int length;
struct block *next;
} BLOCK_NODE, *pBLOCK_NODE;

typedef struct {
pBLOCK_NODE head;
pBLOCK_NODE tail;
int blockNum;
}USED_LINK, FREE_LINK;

typedef enum {FIRST_FIT, NEXT_FIT, BEST_FIT, WORST_FIT} STRATEGY;

void mem_init();
int mem_request(int size, STRATEGY strategy);
bool mem_release(int startPosition);

#endif

mem.cpp

#include <stdio.h>
#include <memory.h>
#include "mem.h"

USED_LINK used_link;
FREE_LINK free_link;

pBLOCK_NODE fromThis = free_link.head;
//char memory[MEM_SIZE];

//内存初始化。
void mem_init() {
//memset(memory, 0, MEM_SIZE);

//使用链表置空。
used_link.head = NULL;
used_link.tail = NULL;
used_link.blockNum = 0;

//空闲连标初始为一个完整的空闲块,块大小为整个内存区。
pBLOCK_NODE tmp = new BLOCK_NODE;
tmp->startPosition = 0;
tmp->endPosition = MEM_SIZE - 1;
tmp->length = MEM_SIZE;
tmp->next = NULL;

free_link.head = tmp;
free_link.tail = tmp;
free_link.blockNum = 1;
}

//内存请求,按一定的分配策略分配,
//并返回分配后内存的首地址。
int mem_request(int size, STRATEGY strategy) {
//若size小于等于零或者大于总内存大小,则错误返回。
if (size <= 0 || size > MEM_SIZE) {
//printf("Memory size error!/n");
return -1;
}

pBLOCK_NODE temp = NULL;

//first_fit
//搜索能够满足请求的内存块。
//若没有满足要求的内存块,则返回-1。
if (strategy == FIRST_FIT) {
temp = free_link.head;
while (free_link.blockNum > 0) {
if (temp == NULL) {
break;
} else if (temp->length >= size) {
break;
} else {
temp = temp->next;
}
}
}

//next_fit strategy
if (strategy == NEXT_FIT) {
int blockNum = free_link.blockNum;
for (int i = 0; i < blockNum; i++) {
if (fromThis == NULL) {
fromThis = free_link.head;
}
if (fromThis->length >= size) {
temp = fromThis;
fromThis = fromThis->next;
break;
} else {
fromThis = fromThis->next;
}
}
}

//best_fit
if (strategy == BEST_FIT) {
int t = MEM_SIZE + 1;
pBLOCK_NODE tp = free_link.head;
while (free_link.blockNum > 0) {
if (tp == NULL) {
break;
} else if (tp->length >= size) {
if (tp->length < t) {
temp = tp;
t = tp->length;
}
tp = tp->next;
} else {
tp = tp->next;
}
}
}

//worst_fit strategy
if (strategy == WORST_FIT) {
int t = 0;
pBLOCK_NODE tp = free_link.head;
while (free_link.blockNum > 0) {
if (tp == NULL) {
break;
} else if (tp->length >= size) {
if (tp->length > t) {
temp = tp;
t = tp->length;
}
tp = tp->next;
} else {
tp = tp->next;
}
}
}

if (temp == NULL) {
//printf("Alloc Failed!/n");
return -1;
} else {
//若存在满足要求的内存块,则创建新的内存块。
pBLOCK_NODE newNode = new BLOCK_NODE;
newNode->startPosition = temp->startPosition;
newNode->endPosition = newNode->startPosition + size - 1;
newNode->length = size;
newNode->next = NULL;

//将新分配的内存块信息插入到使用链表中。
if (used_link.blockNum == 0) {
used_link.head = newNode;
used_link.tail = newNode;
used_link.blockNum = 1;
} else if (used_link.blockNum >= 1) {
//按内存块首地址递增的方式插入。
pBLOCK_NODE preNode = NULL;
pBLOCK_NODE curNode = used_link.head;
if (newNode->startPosition < curNode->startPosition) {
newNode->next = used_link.head;
used_link.head = newNode;
used_link.blockNum++;
} else {
while (curNode->startPosition < newNode->startPosition) {
preNode = curNode;
curNode = curNode->next;
if (curNode == NULL) {
break;
}
}
if (curNode == NULL) {
used_link.tail->next = newNode;
used_link.tail = newNode;
used_link.blockNum++;
} else {
newNode->next = curNode;
preNode->next = newNode;
used_link.blockNum++;
}
}
}

//修改空闲链表中可用内存块的信息。
if (temp->length == size) {
if (temp == free_link.head) {
free_link.head = temp->next;
if (free_link.head == NULL) {
free_link.tail = NULL;
}

delete temp;
free_link.blockNum--;
} else {
pBLOCK_NODE preNode = free_link.head;
pBLOCK_NODE curNode = free_link.head->next;
while (temp != curNode) {
preNode = curNode;
curNode = curNode->next;
}
if (curNode == free_link.tail) {
free_link.tail = preNode;
preNode->next = NULL;
} else {
preNode->next = curNode->next;
}

delete temp;
free_link.blockNum--;
}
} else if (temp->length > size) {
temp->startPosition += size;
temp->length -= size;
}

//返回分配成功后的首地址。
return newNode->startPosition;
}
}

bool mem_release(int startPosition) {
pBLOCK_NODE release_target = used_link.head;
pBLOCK_NODE preNode = NULL;

//此时使用链表为空。
if (release_target == NULL) {
printf("No such alloced memory!/n");
return false;
}
//搜索需要释放的内存块。
while (release_target->startPosition != startPosition) {
preNode = release_target;
release_target = release_target->next;
if (release_target == NULL) {
break;
}
}

//修改使用链表中内存使用信息。删除释放内存的信息结点。
if (release_target == NULL) {
printf("No such alloced memory!/n");
return false;
} else if (release_target == used_link.head && release_target == used_link.tail) {
used_link.head = NULL;
used_link.tail = NULL;
used_link.blockNum--;
} else if (release_target == used_link.head) {
used_link.head = used_link.head->next;
used_link.blockNum--;
} else if (release_target == used_link.tail) {
preNode->next = release_target->next;
used_link.tail = preNode;
used_link.blockNum--;
} else {
preNode->next = release_target->next;
used_link.blockNum--;
}

//修改空闲链表信息,将释放后可重新使用的内存块信息写入空闲链表,
//并进行必要的合并。
pBLOCK_NODE insertBefore = free_link.head;
preNode = NULL;
if (free_link.head == NULL) {
free_link.head = release_target;
free_link.tail = release_target;
release_target->next = NULL;
free_link.blockNum++;
} else if (release_target->startPosition < free_link.head->startPosition) {
if (release_target->endPosition + 1 == free_link.head->startPosition) {
free_link.head->startPosition = release_target->startPosition;
free_link.head->length += release_target->length;
delete release_target;
} else {
release_target->next = free_link.head;
free_link.head = release_target;
free_link.blockNum++;
}
} else {
while (insertBefore->startPosition < release_target->startPosition) {
preNode = insertBefore;
insertBefore = insertBefore->next;
if (insertBefore == NULL) {
break;
}
}
if (insertBefore == NULL) {
if (release_target->startPosition - 1 == preNode->endPosition) {
preNode->endPosition = release_target->endPosition;
preNode->length += release_target->length;
delete release_target;
} else {
preNode->next = release_target;
free_link.tail = release_target;
release_target->next = NULL;
free_link.blockNum++;
}
} else {
if (release_target->startPosition - 1 == preNode->endPosition
&& release_target->endPosition + 1 == insertBefore->startPosition) {
if (insertBefore == free_link.tail) {
preNode->endPosition = insertBefore->endPosition;
preNode->length += (release_target->length + insertBefore->length);
preNode->next = insertBefore->next;

if (fromThis == insertBefore) {
fromThis = preNode;
}

delete insertBefore;
delete release_target;
free_link.tail = preNode;
free_link.blockNum--;
} else {
preNode->endPosition = insertBefore->endPosition;
preNode->length += (release_target->length + insertBefore->length);
preNode->next = insertBefore->next;

if (fromThis == insertBefore) {
fromThis = preNode;
}

delete insertBefore;
delete release_target;
free_link.blockNum--;
}
} else if (release_target->startPosition - 1 == preNode->endPosition) {
preNode->endPosition = release_target->endPosition;
preNode->length += release_target->length;
delete release_target;
} else if (release_target->endPosition + 1 == insertBefore->startPosition) {
insertBefore->startPosition = release_target->startPosition;
insertBefore->length += release_target->length;
delete release_target;
} else {
release_target->next = preNode->next;
preNode->next = release_target;
free_link.blockNum++;
}
}
}

return true;
}

allocate.cpp

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include "mem.h"

#define ROUNDS 1000000
extern FREE_LINK free_link;
extern USED_LINK used_link;

int computeSize(double rangeLow, double rangeHigh);
double computeFraction(STRATEGY strategy, double rangeLow, double rangeHigh);
double averageRand(double min, double max);
void computeAndPrint(double rangeLow, double rangeHigh);

main() {
mem_init();
srand((unsigned)time(NULL));

printf("申请内存占总内存比率为0.02%%--2%%时:/n");
computeAndPrint(0.0002, 0.02);
printf("/n申请内存占总内存比率为0.02%%--8%%时:/n");
computeAndPrint(0.0002, 0.08);
printf("/n申请内存占总内存比率为0.02%%--15%%时:/n");
computeAndPrint(0.0002, 0.15);
printf("/n申请内存占总内存比率为0.02%%--25%%时:/n");
computeAndPrint(0.0002, 0.25);
printf("/n申请内存占总内存比率为0.02%%--40%%时:/n");
computeAndPrint(0.0002, 0.40);
printf("/n申请内存占总内存比率为0.02%%--60%%时:/n");
computeAndPrint(0.0002, 0.60);

return 0;
}

void computeAndPrint(double rangeLow, double rangeHigh) {
printf("first_fit内存平均利用率:/t%f/n", computeFraction(FIRST_FIT, rangeLow, rangeHigh));
printf("next_fit内存平均利用率:/t%f/n", computeFraction(NEXT_FIT, rangeLow, rangeHigh));
printf("best_fit内存平均利用率:/t%f/n", computeFraction(BEST_FIT, rangeLow, rangeHigh));
printf("worst_fit内存平均利用率:/t%f/n", computeFraction(WORST_FIT, rangeLow, rangeHigh));
}

double computeFraction(STRATEGY strategy, double rangeLow, double rangeHigh) {
int pointerTemp = -1;
double fraction = 0;
for (int i = 0; i < ROUNDS; i++) {
int requestSize = 0;
do {
requestSize = computeSize(rangeLow, rangeHigh);
pointerTemp = mem_request(requestSize, strategy);
} while (pointerTemp != -1);

int temp = 0;
pBLOCK_NODE nodeTemp = free_link.head;
while (nodeTemp != NULL) {
temp += nodeTemp->length;
nodeTemp = nodeTemp->next;
}
fraction += (MEM_SIZE - (double)temp)/MEM_SIZE;

if (used_link.blockNum != 0) {
int releaseBlock = rand() % used_link.blockNum;
nodeTemp = used_link.head;
for (int j = 0; j < releaseBlock; j++) {
nodeTemp = nodeTemp->next;
}
mem_release(nodeTemp->startPosition);
}
}
fraction /= ROUNDS;

//printf("Average used fraction: %f/n", fraction);
return fraction;
}

int computeSize(double rangeLow, double rangeHigh) {
return (int)(averageRand(rangeLow, rangeHigh)*MEM_SIZE);
}

double averageRand(double min, double max) {
int minInteger = (int)(min*10000);
int maxInteger = (int)(max*10000);
int diffInteger = maxInteger - minInteger;
double randInteger = (double)rand()/RAND_MAX;
int resultInteger = (int) ( randInteger * diffInteger + minInteger );

return resultInteger/10000.0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: