一、實驗目的
為了合理地分配和使用這些存儲空間,當用戶提出申請主存儲器空間時,存儲管理必須根據申請者的要求,按一定的策略分析主存空間和使用情況,找出足夠的空閑區域給申請者。當作業撤離歸還主存資源時,則存儲管理要收回占用的主存空間。主存的分配和回收的實現是與主存儲器的管理方式有關的,通過本實驗幫助我們理解在不同的存儲管理方式下應怎樣實現主存空間的分配和回收。
用高級語言完成一個主存空間的分配和回收模擬程序,以加深對內存分配方式及其算法的理解。
二、 實驗內容
2.1 模擬包括3部分:
1)實現特定的內存分配算法
2)實現內存回收模擬
3)每種內存分配策略對應的碎片數統計
2.2 固定分區存儲管理
假設內存容量為120KB,並且分別划分成8,16,32,64KB大小的塊各一塊。
一個進程所需要的內存為0到100個KB。同時假設一個進程在運行過程中所需內存的大小不變。
模擬五個進程到達請求分配與運行完回收情況,輸出主存分配表.
2.3 動態分區分配存儲管理
采用連續分配方式之動態分區分配存儲管理,使用首次適應算法、下次適應算法、最佳適應算法和最壞適應算法4種算法完成設計(任選兩種算法)。
(1)在程序運行過程,由用戶指定申請與釋放。
(2)設計一個已占用分區表,以保存某時刻主存空間占用情況。
(3)設計一個空閑分區表,以保存某時刻主存空間剩余情況。
(4)用兩個表的變化情況,反應各進程所需內存的申請與釋放情況。
三、實驗方法、步驟及結果測試
1、源程序
#include<iostream.h> #include<stdlib.h> #define Free 0 //空閑狀態 #define Busy 1 //已用狀態 #define OK 1 //完成 #define ERROR 0 //出錯 #define MAX_length 32767 //最大內存空間為32767KB typedef int Status; int n=0; typedef struct freearea//定義一個空閑區說明表結構 { int ID; //分區號 long size; //分區大小 long address; //分區地址 int state; //狀態 }ElemType; //---------- 線性表的雙向鏈表存儲結構 ------------ typedef struct DuLNode //double linked list { ElemType data; struct DuLNode *prior; //前趨指針 struct DuLNode *next; //后繼指針 }DuLNode,*DuLinkList; DuLinkList block_first; //頭結點 DuLinkList block_last; //尾結點 Status alloc(int);//內存分配 Status free(int); //內存回收 Status First_fit(int,int);//首次適應算法 Status Best_fit(int,int); //最佳適應算法 void show();//查看分配 Status Initblock();//開創空間表 Status Initblock()//開創帶頭結點的內存空間鏈表 { block_first=(DuLinkList)malloc(sizeof(DuLNode)); block_last=(DuLinkList)malloc(sizeof(DuLNode)); block_first->prior=NULL; block_first->next=block_last; block_last->prior=block_first; block_last->next=NULL; block_last->data.address=0; block_last->data.size=MAX_length; block_last->data.ID=0; block_last->data.state=Free; return OK; } //----------------------- 分 配 主 存 ------------------------- Status alloc(int ch) { int ID,request; cout<<"請輸入作業(分區號):"; cin>>ID; cout<<"請輸入需要分配的主存大小(單位:KB):"; cin>>request; if(request<0 ||request==0) { cout<<"分配大小不合適,請重試!"<<endl; return ERROR; } if(ch==2) //選擇最佳適應算法 { if(Best_fit(ID,request)==OK) cout<<"分配成功!"<<endl; else cout<<"內存不足,分配失敗!"<<endl; return OK; } else //默認首次適應算法 { if(First_fit(ID,request)==OK) cout<<"分配成功!"<<endl; else cout<<"內存不足,分配失敗!"<<endl; return OK; } } //------------------ 首次適應算法 ----------------------- Status First_fit(int ID,int request)//傳入作業名及申請量 { //為申請作業開辟新空間且初始化 DuLinkList temp=(DuLinkList)malloc(sizeof(DuLNode)); temp->data.ID=ID; temp->data.size=request; temp->data.state=Busy; DuLNode *p=block_first->next; while(p) { if(p->data.state==Free && p->data.size==request) {//有大小恰好合適的空閑塊 p->data.state=Busy; p->data.ID=ID; return OK; break; } if(p->data.state==Free && p->data.size>request) {//有空閑塊能滿足需求且有剩余" temp->prior=p->prior; temp->next=p; temp->data.address=p->data.address; p->prior->next=temp; p->prior=temp; p->data.address=temp->data.address+temp->data.size; p->data.size-=request; return OK; break; } p=p->next; } return ERROR; } //-------------------- 最佳適應算法 ------------------------ Status Best_fit(int ID,int request) { int ch; //記錄最小剩余空間 DuLinkList temp=(DuLinkList)malloc(sizeof(DuLNode)); temp->data.ID=ID; temp->data.size=request; temp->data.state=Busy; DuLNode *p=block_first->next; DuLNode *q=NULL; //記錄最佳插入位置 while(p) //初始化最小空間和最佳位置 { if(p->data.state==Free && (p->data.size>request || p->data.size==request) ) { q=p; ch=p->data.size-request; break; } p=p->next; } while(p) { if(p->data.state==Free && p->data.size==request) {//空閑塊大小恰好合適 p->data.ID=ID; p->data.state=Busy; return OK; break; } if(p->data.state==Free && p->data.size>request) {//空閑塊大於分配需求 if(p->data.size-request<ch)//剩余空間比初值還小 { ch=p->data.size-request;//更新剩余最小值 q=p;//更新最佳位置指向 } } p=p->next; } if(q==NULL) return ERROR;//沒有找到空閑塊 else {//找到了最佳位置並實現分配 temp->prior=q->prior; temp->next=q; temp->data.address=q->data.address; q->prior->next=temp; q->prior=temp; q->data.address+=request; q->data.size=ch; return OK; } } //----------------------- 主 存 回 收 -------------------- Status free(int ID) { DuLNode *p=block_first; while(p) { if(p->data.ID==ID) { p->data.state=Free; p->data.ID=Free; if(p->prior->data.state==Free)//與前面的空閑塊相連 { p->prior->data.size+=p->data.size; p->prior->next=p->next; p->next->prior=p->prior; } if(p->next->data.state==Free)//與后面的空閑塊相連 { p->data.size+=p->next->data.size; p->next->next->prior=p; p->next=p->next->next; } break; } p=p->next; } return OK; } //--------------- 顯示主存分配情況 ------------------ void show() { cout<<"***********-----------------************\n"; cout<<"**** 主 存 分 配 情 況 ****\n"; cout<<"***********-----------------************\n"; DuLNode *p=block_first->next; while(p) { cout<<"分 區 號:"; if(p->data.ID==Free) cout<<"Free"<<endl; else cout<<p->data.ID<<endl; cout<<"起始地址:"<<p->data.address<<endl; cout<<"分區大小:"<<p->data.size<<" KB"<<endl; cout<<"狀 態:"; if(p->data.state==Free) cout<<"空 閑"<<endl; else cout<<"已分配!"<<endl; cout<<"-----------------------"<<endl; p=p->next; } } //----------------------- 主 函 數--------------------------- void main() { int ch,d=0;//算法選擇標記 cout<<"1.首次適應算法 2.最佳適應算法 0.退出\n"; cout<<"請選擇分配算法:"; cin>>ch; if(ch==0||ch==1||ch==2) d++; while(d==0) { cout<<"請選擇正確的數字0 ,1 或2"<<endl; cin>>ch; if(ch==0||ch==1||ch==2) d++; } if(ch==0) exit(0); if(n==0) Initblock(); //開創空間表 int choice; //操作選擇標記 while(1) { cout<<"********************************************\n"; cout<<"** 1: 分配內存 2: 回收內存 **\n"; cout<<"** 3: 查看分配 0: 返 回 **\n"; cout<<"********************************************\n"; cout<<"請輸入您的操作 :"; cin>>choice; if(choice==1) { alloc(ch); // 分配內存 n++; } else if(choice==2) // 內存回收 { int ID; cout<<"請輸入您要釋放的分區號:"; cin>>ID; free(ID); n++; } else if(choice==3) { show();//顯示主存 n++; } else if(choice==0) { main(); //退出 n++; } else //輸入操作有誤 { cout<<"輸入有誤,請重試!\n"<<endl; continue; } } }
2.運行結果
4.結果分析
本次實驗對於實驗的要求不是很能理解,通過對課本的查閱和網上的資料才有點明白。參考網上的實驗寫出的代碼,有不足的地方,以后改正。