姓名:吴永锋

学号:201821121051

班级:计算1812

动态分区分配是根据进程的实际需要,动态的为之分配内存空间。而在实现可变分区分配时,将涉及到分区分配中

所用的数据结构、分区分配算法和分区的分配与内存回收的过程。

分区分配中的数据结构:(1)描述空闲块的数据结构。(2)内存块的描述。

1. 记录内存空间使用情况

分配内存区块表,包含被分配的内存区起始地址及大小和使用该内存的进程pid。

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

2 typedef structallocated_block{3 intpid;4 int size; //进程大小

5 int start_addr; //进程分配到的内存块的起始地址

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

7 struct allocated_block *next; //指向下一个进程控制块

8 }AB;9

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

11 AB *allocated_block_head = NULL;

2. 记录空闲分区

空闲内存区块表,包含该空闲区的起始地址以及大小。程序初始化链表仅一个节点,大小为默认大小。

1 /*描述每一个空闲块的数据结构*/

2 typedef structfree_block_type{3 int size; //空闲块大小

4 int start_addr; //空闲块起始位置

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

6 }FBT;7

8 FBT *free_block;//指向内存中空闲块链表的首指针

3. 内存分配算法

首次适应算法(First Fit):从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给

作业,这种方法的目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到

高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。

1 //执行分配内存

2 void do_allocate_mem(AB *ab){3 int request = ab->size;4 FBT *tmp =free_block;5 while(tmp !=NULL){6 if(tmp->size >=request){7 //分配

8 ab->start_addr = tmp->start_addr;9 int shengyu = tmp->size -request;10 tmp->size =shengyu;11 tmp->start_addr = tmp->start_addr +request;12

13 return;14 }15 tmp = tmp->next;16 }17 }18

19 int allocate_mem(AB *ab){20 /*分配内存模块*/

21 FBT *fbt,*pre;22 int request_size=ab->size;23 fbt = pre =free_block;24 /*

25 根据当前算法在空闲分区链表中搜索合适空闲分区进行分配,26 分配时注意以下情况:27 1. 找到可满足空闲分区且分配后剩余空间足够大,则分割28 2. 找到可满足空闲分区且但分配后剩余空间比较小,则一起分配29 3. 找不可满足需要的空闲分区但空闲分区之和能满足需要,30 则采用内存紧缩技术,进行空闲分区的合并,然后再分配31 4. 在成功分配内存后,应保持空闲分区按照相应算法有序32 5. 分配成功则返回1,否则返回-133 */

34 //尝试寻找可分配空闲,具体结果在函数中有解释

35 int f =find_free_mem(request_size);36 if(f == -1){37 //不够分配

38 printf("空闲内存不足,内存分配失败!\n");39 return -1;40 }else{41 if(f == 0){42 //需要内存紧缩才能分配

43 memory_compact();44 }45 //执行分配

46 do_allocate_mem(ab);47 }48 //重新排布空闲分区

49 rearrange(ma_algorithm);50 return 1;51 }52 //为进程分配内存

53 intalloc_process(Prc prc){54 AB *ab;55 intret;56 ab = (AB*)malloc(sizeof(AB));57 if(!ab) exit(-5);58 /*为ab赋值*/

59 ab->next=NULL;60 pid++;//记录id

61 strcpy(ab->process_name,prc.process_name);62 ab->pid =pid;63 ab->size=prc.size+rand()%ALLOC_SIZE;//随机分配内存

64

65 ret = allocate_mem(ab); //从空闲分区分配内存,ret==1表示分配成功

66 if((ret == 1) && (allocated_block_head ==NULL)){67 /*如果此时allocated_block_head尚未赋值,则赋值*/

68 allocated_block_head =ab;69 return 1;70 }else if(ret == 1){71 /*分配成功,将该分配块的描述插入已分配链表*/

72 ab->next =allocated_block_head;73 allocated_block_head =ab;74 return 2;75 }else if(ret == -1){76 //分配不成功

77 printf("\e[0;31;1m 内存分配失败! \e[0m\n");78 free(ab);79 return -1;80 }81 return 3;82 }83

84 voidrearrange_FF(){85 /*首次适应算法,空闲区大小按起始地址升序排序*/

86 //这里使用冒泡排序方法

87 if(free_block == NULL || free_block->next ==NULL)88 return;89 FBT *t1,*t2,*head;90 head =free_block;91 for(t1 = head->next;t1;t1 = t1->next){92 for(t2 = head;t2 != t1;t2=t2->next){93 if(t2->start_addr > t2->next->start_addr){94 int tmp = t2->start_addr;95 t2->start_addr = t2->next->start_addr;96 t2->next->start_addr =tmp;97

98 tmp = t2->size;99 t2->size = t2->next->size;100 t2->next->size =tmp;101 }102 }103 }104 }

4. 内存释放算法

找到对应的链表节点,释放释放杀死进程的内存块,归还进程的已分配的存储空间,按大小从小到大排序,销毁杀死进程的结点。

1 //释放链表节点

2 int dispose(AB *free_ab){3 /*释放ab数据结构节点*/

4 AB *pre,*ab;5 if(free_ab ==allocated_block_head){6 //如果要是释放第一个节点

7 allocated_block_head = allocated_block_head->next;8 free(free_ab);9 return 1;10 }11 pre =allocated_block_head;12 ab = allocated_block_head->next;13 while(ab!=free_ab){14 pre =ab;15 ab = ab->next;16 }17 pre->next = ab->next;18 free(ab);19 return 2;20 }21

22 //更新分区表

23 int free_mem(AB *ab){24 /*将ab所表示的已分配区归还,并进行可能的合并*/

25 int algorithm =ma_algorithm;26 FBT *fbt,*pre,*work;27 fbt = (FBT*)malloc(sizeof(FBT));28 if(!fbt) return -1;29 /*

30 进行可能的合并,基本策略如下?31 1. 将新释放的结点插入到空闲分区队列末尾?32 2. 对空闲链表按照地址有序排列?33 3. 检查并合并相邻的空闲分区?34 4. 将空闲链表重新按照当前算法排序35 */

36 fbt->size = ab->size;37 fbt->start_addr = ab->start_addr;38

39 //插至末尾

40 work =free_block;41 if(work ==NULL){42 free_block =fbt;43 fbt->next ==NULL;44 }else{45 while(work ->next !=NULL){46 work = work->next;47 }48 fbt->next = work->next;49 work->next =fbt;50 }51 //按地址重新排布

52 rearrange_FF();53

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

55 pre =free_block;56 while(pre->next){57 work = pre->next;58 if(pre->start_addr + pre->size == work->start_addr ){59 pre->size = pre->size + work->size;60 pre->next = work->next;61 free(work);62 continue;63 }else{64 pre = pre->next;65 }66 }67

68 //按照当前算法排序

69 rearrange(ma_algorithm);70 return 1;71 }72

73 int kill_process(intpid){74 AB *ab;75 ab =find_process(pid);76 if(ab!=NULL){77 free_mem(ab); //释放ab所表示的分配表

78 dispose(ab); //释放ab数据结构节点

79 return 0;80 }else{81 return -1;82 }83 }

5. 运行结果

(1)产生测试数据

随机为3个进程分配、释放内存10次以上,即随机产生10组以上数据:(进程Pi 分配内存大小) 或者 (进程Pi结束)

int main(int argc, char const *argv[]){/*code*/

intsel1,sel2;int total=0; //记录分配内存的次数

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

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

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

srand( (unsigned)time( NULL ) );for(int i=0;i

{/*sel1=0表示为某进程分配内存空间

sel1=1表示为释放某进程占用的内存空间*/sel1=rand()%2;int count=0;//统计三个进程中有多少个进程已经分配内存

for(int j=0;j

count++;

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

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

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

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

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

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

do{

sel2=rand()%PROCESS_NUM;

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

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

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

total++;

display_mem_usage();//显示

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

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

do{

sel2=rand()%PROCESS_NUM;

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

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

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

display_mem_usage();//显示

}

}

}

(2)解释结果

程序中定义了内存大小为1024,

第一次,为进程process-03分配内存,起始地址为0,大小为106,分配后剩余空闲分区内存起始地址为106,大小为918。

第二次,为进程process-01分配内存,起始地址为106,大小为57,分配后剩余空闲分区内存起始地址为163,大小为861。

第三次,释放进程process-01的内存空间,释放后剩余空闲分区内存起始地址为106,大小为918。

第四次,释放进程process-03的内存空间,释放后剩余空闲分区内存起始地址为0,大小为1024。

可变分区存储管理实验报告总结_操作系统第5次实验报告:内存管理相关推荐

  1. 16281053_杨瑷彤_操作系统第五次实验-文件系统

    16281053_杨瑷彤_操作系统第五次实验-文件系统 源代码链接:https://github.com/rdjyat/operating-system/tree/master/操作系统实验五 1.实 ...

  2. 可变分区存储管理实验报告总结_操作系统实验报告-可变分区存储管理方式的内存分配回收...

    一.实验目的 ( 1 )深入了解可变分区存储管理方式的内存分配回收的实现. 二.实验内容 编写程序完成可变分区存储管理方式的内存分配回收,要求有内存空间分配表, 并采用最优适应算法完成内存的分配与回收 ...

  3. c语言上机实验指导西南交通大学,操作系统原理与应用实验指导书-西南交通大学.doc...

    操作系统原理与应用实验指导书-西南交通大学 <操作系统原理与应用> 实验指导书 西南交通大学经济管理学院 电子商务与信息管理系 王明亮编写 2007年7月 实验名称:1. 安装Linux操 ...

  4. 切片分析报告格式_疫情舆情分析研判报告怎么撰写?2020舆情报告格式

    ​疫情舆情分析研判报告撰写不像疫情舆情信息监测与搜集工作那么容易,它需要从数据出发,以内容为支撑,要先对疫情舆情信息进行整理汇总,再处理.分析和研判.因此,报告撰写难度大,毕竟它是整个舆情分析研判最终 ...

  5. python程序设计实验指导书_《Python程序设计》实验指导书.pdf

    Python < 程序设计>实验指导书 董付国 <Python 程序设计 (第2 版)> <Python 程序设计基础 (第2 版)> <Python 可以这 ...

  6. Linux操作系统原理与应用04:内存管理

    目录 1. Linux内存管理概述 1.1 内存的层次结构 1.2 虚拟内存概述 1.2.1 虚拟内存基本思想 1.2.2 进程虚拟地址空间 1.3 内核空间到物理空间的映射 1.3.1 内核空间的线 ...

  7. 【操作系统】第三章:内存管理

    文章目录 3.1.1 内存的基础知识 什么是内存?有何作用 指令的工作原理 进程装入内存的三种方式 从写程序到程序运行 3.1.2 内存管理的概念 内存空间的分配与回收 内存空间的扩展 地址转换 内存 ...

  8. java 第六次实验_操作系统第六次实验报告——使用信号量解决哲学家进餐问题...

    0 个人信息 张樱姿 201821121038 计算1812 1 实验目的 通过编程进一步了解信号量. 2 实验内容 在服务器上用Vim编写一个程序:使用信号量解决任一个经典PV问题,测试给出结果,并 ...

  9. MySQL实验超市管理系统_超市会员管理系统(数据库)实验报告.doc

    PAGE PAGE 2 学号: 成绩:________ 数据库综合实验报告 院 系 计算机与电子信息学院 专 业 计算机科学与技术 班 级 xxxxxxxxxxx 设计题目 超市会员管理系统 姓 名 ...

最新文章

  1. 1199: 房间安排
  2. 微信服务号、公众号、企业号注册
  3. 20年前的程序员什么样?从版主到架构大牛的成长之路
  4. HDU 2504 又见GCD
  5. Kubernetes集群部署
  6. XCode中设置字体大小
  7. java单例模式的应用_java单例模式的简单应用例子
  8. Java中获取系统日期时间/系统时间
  9. LeetCode 26. 删除排序数组中的重复项
  10. 访问php文件显示500错误,nginx 访问.php文件正常,访问.html文件500错误
  11. 内存很空却频繁gc_记一次不太成功的频繁 full gc 排查过程
  12. 2005年1月8日——最伤心的一天
  13. 子树大小平衡树(SizeBalancedTree,SBT)——模板
  14. 分布式事务解决方案之2PC(两阶段提交)介绍
  15. html 文字 向上滚动代码,文字向上滚动代码
  16. 小学阅读方法六种_小学数学阅读理解解题技巧,附常见的6种方法
  17. OpenWrt开发必备软件模块——网络管理(CWMP、SSH、QoS、SMTP、NTP、uHTTPd)
  18. 利用masm32输出PE文件头的基本属性
  19. 纯css实现各种箭头图片效果
  20. 荣耀手机环比倍增,小米有点受伤

热门文章

  1. python二级考time库吗_学python第十七节:time库的学习
  2. 【安全漏洞】SRC另类思路分享:不受限制的资源调用
  3. 【网络安全】身份验证凭证为何如此重要?
  4. 1103 Integer Factorization (30 分)【难度: 中 / 爆搜】
  5. 【PAT乙级】1029 旧键盘 (20 分)
  6. pair的常见用法详解
  7. Struts2的下载安装
  8. MySQL流程控制的使用
  9. 安装cv2(opencv-python)遇到的问题
  10. 400 多页的 Java 面试笔记,各个公司面试真题!