操作系统第五次实验报告——内存管理

编程

c语言实现最佳分配进程内存空间算法

0 个人信息

  • 张樱姿
  • 201821121038
  • 计算1812

1 实验目的

  • 通过编程进一步了解内存管理。

2 实验内容

  • 在服务器上用Vim编写一个程序:仿真实现某个内存管理算法,测试给出结果,并对解释运行结果。

3 实验报告

  3.1 记录内存空间使用情况

   使用链表记录内存空间使用情况。

 1//每个进程分配到的内存块

2 typedef struct allocated_block{

3int pid; //进程号

4int size; //进程分配到的内存块大小

5int start_addr; //内存块起始地址

6char process_name[NAME_LEN]; //进程名

7struct allocated_block *next; //指向下一个内存块的指针

8}AB;

9

10//进程分配内存块链表的首指针

11 AB *allocated_block_head = NULL;

  3.2 记录空闲分区

   同样也使用链表来记录空闲分区。

1//每个空闲块

2 typedef struct free_block_type{

3int size; //空闲块大小

4int start_addr; //空闲块起始地址

5struct free_block_type *next; //指向下一个空闲块

6}FBT;

7

8//指向内存中空闲块链表的首指针

9 FBT *free_block;

  3.3 内存分配算法

   最佳分配算法(Best Fit Allocation)的原理是空闲分区列表按照大小排序,在分配时,查找一个合适的分区(分配n字节分区时,查找并使用不小于n的最小空间分区);在释放时,查找并且合并临近的空闲分区(如果找到的话)。

 1//执行分配内存

2void do_allocate_mem(AB *ab){

3int request = ab->size;

4 FBT *tmp = free_block;

5while(tmp != NULL){

6if(tmp->size >= request){

7//分配

8 ab->start_addr = tmp->start_addr;

9int shengyu = tmp->size - request;

10 tmp->size = shengyu;

11 tmp->start_addr = tmp->start_addr + request;

12

13return ;

14 }

15 tmp = tmp->next;

16 }

17}

18

19//分配内存模块

20int allocate_mem(AB *ab){

21 FBT *fbt,*pre;

22int request_size=ab->size;

23 fbt = pre = free_block;

24//尝试寻找可分配空闲

25int f = find_free_mem(request_size);

26if(f == -1){

27//不够分配

28 printf("空闲内存不足,内存分配失败!

");

29return -1;

30 }else{

31if(f == 0){

32//需要内存紧缩才能分配

33 memory_compact();

34 }

35//执行分配

36 do_allocate_mem(ab);

37 }

38//重新排布空闲分区

39 rearrange(ma_algorithm);

40return1;

41}

42

43//最佳适应算法,空闲分区按大小从小到大排序

44void rearrange_BF(){

45if(free_block == NULL || free_block->next == NULL)

46return;

47 FBT *t1,*t2,*head;

48 head = free_block;

49//遍历整个空闲块列表,比较找到最小的一块空闲块

50for(t1 = head->next;t1;t1 = t1->next){

51for(t2 = head;t2 != t1;t2=t2->next){

52if(t2->size > t2->next->size){

53int tmp = t2->start_addr;

54 t2->start_addr = t2->next->start_addr;

55 t2->next->start_addr = tmp;

56

57 tmp = t2->size;

58 t2->size = t2->next->size;

59 t2->next->size = tmp;

60 }

61 }

62 }

63 }

  3.4 内存释放算法

 1//释放链表节点

2int dispose(AB *free_ab){

3 AB *pre,*ab;

4if(free_ab == allocated_block_head){

5//如果要释放第一个节点

6 allocated_block_head = allocated_block_head->next;

7free(free_ab);

8return1;

9 }

10 pre = allocated_block_head;

11 ab = allocated_block_head->next;

12while(ab!=free_ab){

13 pre = ab;

14 ab = ab->next;

15 }

16 pre->next = ab->next;

17free(ab);

18return2;

19}

20

21//更新分区表

22int free_mem(AB *ab){

23//将ab所表示的已分配区归还,并进行可能的合并

24int algorithm = ma_algorithm;

25 FBT *fbt,*pre,*work;

26 fbt = (FBT*)malloc(sizeof(FBT));

27if(!fbt) return -1;

28 fbt->size = ab->size;

29 fbt->start_addr = ab->start_addr;

30

31//插至末尾

32 work = free_block;

33if(work == NULL){

34 free_block = fbt;

35 fbt->next == NULL;

36 }else{

37while(work ->next != NULL){

38 work = work->next;

39 }

40 fbt->next = work->next;

41 work->next = fbt;

42 }

43//按地址重新排布

44 rearrange_BF();

45

46//合并可能分区;即若两空闲分区相连则合并

47 pre = free_block;

48while(pre->next){

49 work = pre->next;

50if(pre->start_addr + pre->size == work->start_addr ){

51 pre->size = pre->size + work->size;

52 pre->next = work->next;

53free(work);

54continue;

55 }else{

56 pre = pre->next;

57 }

58 }

59//按照当前算法排序

60 rearrange(ma_algorithm);

61return1;

62}

63

64//释放已分配的内存空间,删除描述该进程分配到的内存块的节点

65int kill_process(int pid){

66 AB *ab;

67 ab = find_process(pid);

68if(ab!=NULL){

69//释放ab所表示的分配表

70 free_mem(ab);

71//释放ab数据结构节点

72 dispose(ab);

73return0;

74 }else{

75return -1;

76 }

77 }

  3.5 运行结果

    3.5.1 产生测试数据

      随机为3个进程分配、释放内存10次以上,即随机产生10组以上数据。

 1int main(int argc, charconst *argv[]){

2/*

3 sel1=0表示为某进程分配内存空间

4 sel1=1表示为释放某进程占用的内存空间

5*/

6int sel1,sel2;

7int total=0; //记录分配内存的次数

8 free_block = init_free_block(mem_size); //初始化空闲区

9

10 Prc prc[PROCESS_NUM];//存放要加载的进程

11 init_program(prc,PROCESS_NUM);//对这几个程进程进行初始化

12 srand( (unsigned)time( NULL ) );

13

14for(int i=0;i<DATA_NUM;++i)

15 {

16 sel1=rand()%2;

17int count=0;

18//统计三个进程中有多少个进程已经分配内存

19for(int j=0;j<PROCESS_NUM;++j){

20if(prc[j].pid!=-1)

21 count++;

22 }

23//如果全部分配进程或者进程分配到达5次,那么就不能继续分配内存改为释放内存

24if((count==PROCESS_NUM && sel1==0)||total==5)

25 sel1=1;

26//如果全部未分配进程,那么就不能继续释放内存

27if(count==0 && sel1==1)

28 sel1=0;

29if(sel1==0)//为进程分配内存

30 {

31//随机找到一个未分配内存的进程

32do{

33 sel2=rand()%PROCESS_NUM;

34 }while(prc[sel2].pid!=-1);

35 alloc_process(prc[sel2]);//分配内存空间

36 prc[sel2].pid=pid;//改变标记

37 total++;

38 display_mem_usage();//显示

39 }

40else//释放进程占用的内存空间

41 {

42//随机找到一个可释放进程

43do{

44 sel2=rand()%PROCESS_NUM;

45 }while(prc[sel2].pid==-1);

46 kill_process(prc[sel2].pid);//释放内存空间

47 prc[sel2].pid=-1;//改变标记

48 display_mem_usage();//显示

49 }

50 }

51 }

    3.5.2 解释结果

     初始的空闲块大小1024KB,

     ①第一次分配结果:

     为PID为1的进程分配大小为24KB的内存空间,起始地址为0,分配完成后的空闲空间为1000KB,起始地址为24。

    ②第二次分配结果:

     为PID为2的进程分配大小为74KB的内存空间,起始地址为24,分配完成后的空闲空间为926KB,起始地址为98。

    ③第三次分配结果:

    为PID为3的进程分配大小为36KB的内存空间,起始地址为98,分配完成后的空闲空间为890KB,起始地址为134。     

    ④第四次分配结果:

    将PID为3的进程释放,空闲空间变为926KB,起始地址为98。

    ⑤第五次分配结果:

     将PID为1的进程释放,空闲空间变为两块,一块大小926KB,起始地址为98。另一块大小24KB,起始地址为0。

4 References

  •  https://github.com/City-Zero/LinuxTest/tree/96c823cf1ed5aaaa401d3a3c9e3e4f7948def52b/OSex/mem_manager

 

  

 

    

以上是 操作系统第五次实验报告——内存管理 的全部内容, 来源链接: utcz.com/z/516518.html

回到顶部