可变分区存储管理实验报告总结_操作系统第5次实验报告:内存管理
姓名:吳永鋒
學號: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次实验报告:内存管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 单元格内多个姓名拆分成一列_excel单
- 下一篇: python 数据结构包_Python