可变分区存储管理实验报告总结_操作系统第5次实验报告:内存管理
姓名:吳永鋒
學(xué)號(hào):201821121051
班級(jí):計(jì)算1812
動(dòng)態(tài)分區(qū)分配是根據(jù)進(jìn)程的實(shí)際需要,動(dòng)態(tài)的為之分配內(nèi)存空間。而在實(shí)現(xiàn)可變分區(qū)分配時(shí),將涉及到分區(qū)分配中
所用的數(shù)據(jù)結(jié)構(gòu)、分區(qū)分配算法和分區(qū)的分配與內(nèi)存回收的過(guò)程。
分區(qū)分配中的數(shù)據(jù)結(jié)構(gòu):(1)描述空閑塊的數(shù)據(jù)結(jié)構(gòu)。(2)內(nèi)存塊的描述。
1. 記錄內(nèi)存空間使用情況
分配內(nèi)存區(qū)塊表,包含被分配的內(nèi)存區(qū)起始地址及大小和使用該內(nèi)存的進(jìn)程pid。
1 /*每個(gè)進(jìn)程分配到的內(nèi)存塊描述*/
2 typedef structallocated_block{3 intpid;4 int size; //進(jìn)程大小
5 int start_addr; //進(jìn)程分配到的內(nèi)存塊的起始地址
6 char process_name[NAME_LEN]; //進(jìn)程名
7 struct allocated_block *next; //指向下一個(gè)進(jìn)程控制塊
8 }AB;9
10 /*進(jìn)程分配內(nèi)存塊鏈表的首指針*/
11 AB *allocated_block_head = NULL;
2. 記錄空閑分區(qū)
空閑內(nèi)存區(qū)塊表,包含該空閑區(qū)的起始地址以及大小。程序初始化鏈表僅一個(gè)節(jié)點(diǎn),大小為默認(rèn)大小。
1 /*描述每一個(gè)空閑塊的數(shù)據(jù)結(jié)構(gòu)*/
2 typedef structfree_block_type{3 int size; //空閑塊大小
4 int start_addr; //空閑塊起始位置
5 struct free_block_type *next; //指向下一個(gè)空閑塊
6 }FBT;7
8 FBT *free_block;//指向內(nèi)存中空閑塊鏈表的首指針
3. 內(nèi)存分配算法
首次適應(yīng)算法(First Fit):從空閑分區(qū)表的第一個(gè)表目起查找該表,把最先能夠滿(mǎn)足要求的空閑區(qū)分配給
作業(yè),這種方法的目的在于減少查找時(shí)間。為適應(yīng)這種算法,空閑分區(qū)表(空閑區(qū)鏈)中的空閑分區(qū)要按地址由低到
高進(jìn)行排序。該算法優(yōu)先使用低址部分空閑區(qū),在低址空間造成許多小的空閑區(qū),在高地址空間保留大的空閑區(qū)。
1 //執(zhí)行分配內(nèi)存
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 /*分配內(nèi)存模塊*/
21 FBT *fbt,*pre;22 int request_size=ab->size;23 fbt = pre =free_block;24 /*
25 根據(jù)當(dāng)前算法在空閑分區(qū)鏈表中搜索合適空閑分區(qū)進(jìn)行分配,26 分配時(shí)注意以下情況:27 1. 找到可滿(mǎn)足空閑分區(qū)且分配后剩余空間足夠大,則分割28 2. 找到可滿(mǎn)足空閑分區(qū)且但分配后剩余空間比較小,則一起分配29 3. 找不可滿(mǎn)足需要的空閑分區(qū)但空閑分區(qū)之和能滿(mǎn)足需要,30 則采用內(nèi)存緊縮技術(shù),進(jìn)行空閑分區(qū)的合并,然后再分配31 4. 在成功分配內(nèi)存后,應(yīng)保持空閑分區(qū)按照相應(yīng)算法有序32 5. 分配成功則返回1,否則返回-133 */
34 //嘗試尋找可分配空閑,具體結(jié)果在函數(shù)中有解釋
35 int f =find_free_mem(request_size);36 if(f == -1){37 //不夠分配
38 printf("空閑內(nèi)存不足,內(nèi)存分配失敗!\n");39 return -1;40 }else{41 if(f == 0){42 //需要內(nèi)存緊縮才能分配
43 memory_compact();44 }45 //執(zhí)行分配
46 do_allocate_mem(ab);47 }48 //重新排布空閑分區(qū)
49 rearrange(ma_algorithm);50 return 1;51 }52 //為進(jìn)程分配內(nèi)存
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;//隨機(jī)分配內(nèi)存
64
65 ret = allocate_mem(ab); //從空閑分區(qū)分配內(nèi)存,ret==1表示分配成功
66 if((ret == 1) && (allocated_block_head ==NULL)){67 /*如果此時(shí)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 內(nèi)存分配失敗! \e[0m\n");78 free(ab);79 return -1;80 }81 return 3;82 }83
84 voidrearrange_FF(){85 /*首次適應(yīng)算法,空閑區(qū)大小按起始地址升序排序*/
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. 內(nèi)存釋放算法
找到對(duì)應(yīng)的鏈表節(jié)點(diǎn),釋放釋放殺死進(jìn)程的內(nèi)存塊,歸還進(jìn)程的已分配的存儲(chǔ)空間,按大小從小到大排序,銷(xiāo)毀殺死進(jìn)程的結(jié)點(diǎn)。
1 //釋放鏈表節(jié)點(diǎn)
2 int dispose(AB *free_ab){3 /*釋放ab數(shù)據(jù)結(jié)構(gòu)節(jié)點(diǎn)*/
4 AB *pre,*ab;5 if(free_ab ==allocated_block_head){6 //如果要是釋放第一個(gè)節(jié)點(diǎn)
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 //更新分區(qū)表
23 int free_mem(AB *ab){24 /*將ab所表示的已分配區(qū)歸還,并進(jìn)行可能的合并*/
25 int algorithm =ma_algorithm;26 FBT *fbt,*pre,*work;27 fbt = (FBT*)malloc(sizeof(FBT));28 if(!fbt) return -1;29 /*
30 進(jìn)行可能的合并,基本策略如下?31 1. 將新釋放的結(jié)點(diǎn)插入到空閑分區(qū)隊(duì)列末尾?32 2. 對(duì)空閑鏈表按照地址有序排列?33 3. 檢查并合并相鄰的空閑分區(qū)?34 4. 將空閑鏈表重新按照當(dāng)前算法排序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 //合并可能分區(qū);即若兩空閑分區(qū)相連則合并
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 //按照當(dāng)前算法排序
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數(shù)據(jù)結(jié)構(gòu)節(jié)點(diǎn)
79 return 0;80 }else{81 return -1;82 }83 }
5. 運(yùn)行結(jié)果
(1)產(chǎn)生測(cè)試數(shù)據(jù)
隨機(jī)為3個(gè)進(jìn)程分配、釋放內(nèi)存10次以上,即隨機(jī)產(chǎn)生10組以上數(shù)據(jù):(進(jìn)程Pi 分配內(nèi)存大小) 或者 (進(jìn)程Pi結(jié)束)
int main(int argc, char const *argv[]){/*code*/
intsel1,sel2;int total=0; //記錄分配內(nèi)存的次數(shù)
free_block = init_free_block(mem_size); //初始化空閑區(qū)
Prc prc[PROCESS_NUM];//存放要加載的進(jìn)程
init_program(prc,PROCESS_NUM);//對(duì)這幾個(gè)程進(jìn)程進(jìn)行初始化
srand( (unsigned)time( NULL ) );for(int i=0;i
{/*sel1=0表示為某進(jìn)程分配內(nèi)存空間
sel1=1表示為釋放某進(jìn)程占用的內(nèi)存空間*/sel1=rand()%2;int count=0;//統(tǒng)計(jì)三個(gè)進(jìn)程中有多少個(gè)進(jìn)程已經(jīng)分配內(nèi)存
for(int j=0;j
count++;
}//如果全部分配進(jìn)程或者進(jìn)程分配到達(dá)5次,那么就不能繼續(xù)分配內(nèi)存改為釋放內(nèi)存
if((count==PROCESS_NUM && sel1==0)||total==5)
sel1=1;//如果全部未分配進(jìn)程,那么就不能繼續(xù)釋放內(nèi)存
if(count==0 && sel1==1)
sel1=0;if(sel1==0)//為進(jìn)程分配內(nèi)存
{//隨機(jī)找到一個(gè)未分配內(nèi)存的進(jìn)程
do{
sel2=rand()%PROCESS_NUM;
}while(prc[sel2].pid!=-1);
alloc_process(prc[sel2]);//分配內(nèi)存空間
prc[sel2].pid=pid;//改變標(biāo)記
total++;
display_mem_usage();//顯示
}else//釋放進(jìn)程占用的內(nèi)存空間
{//隨機(jī)找到一個(gè)可釋放進(jìn)程
do{
sel2=rand()%PROCESS_NUM;
}while(prc[sel2].pid==-1);
kill_process(prc[sel2].pid);//釋放內(nèi)存空間
prc[sel2].pid=-1;//改變標(biāo)記
display_mem_usage();//顯示
}
}
}
(2)解釋結(jié)果
程序中定義了內(nèi)存大小為1024,
第一次,為進(jìn)程process-03分配內(nèi)存,起始地址為0,大小為106,分配后剩余空閑分區(qū)內(nèi)存起始地址為106,大小為918。
第二次,為進(jìn)程process-01分配內(nèi)存,起始地址為106,大小為57,分配后剩余空閑分區(qū)內(nèi)存起始地址為163,大小為861。
第三次,釋放進(jìn)程process-01的內(nèi)存空間,釋放后剩余空閑分區(qū)內(nèi)存起始地址為106,大小為918。
第四次,釋放進(jìn)程process-03的內(nèi)存空間,釋放后剩余空閑分區(qū)內(nèi)存起始地址為0,大小為1024。
總結(jié)
以上是生活随笔為你收集整理的可变分区存储管理实验报告总结_操作系统第5次实验报告:内存管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 单元格内多个姓名拆分成一列_excel单
- 下一篇: 万能系统卸载器免root_这下舒服了!一