要求:
系統(tǒng)根據(jù)申請者的要求,按照一定的分配策略分析內(nèi)存空間的使用情況,找出能滿足請求的空閑區(qū),分給申請者;當(dāng)程序執(zhí)行完畢或主動歸還內(nèi)存資源時,系統(tǒng)要收回它所占用的內(nèi)存空間或它歸還的部分內(nèi)存空間,主存分配算法使用最壞適應(yīng)分配算法。
程序運(yùn)行時根據(jù)文件內(nèi)容初始化空閑區(qū)表,文件內(nèi)容為每行兩項:起始地址 長度 中間以逗號隔開,文件內(nèi)容如下:
10,313,417,230,838,7
可變分區(qū)存儲管理的內(nèi)存分配方案一般采用"已分配區(qū)表"和"空閑區(qū)表"來記錄主存已分配和未分配的情況,本例中采用單向鏈表方式來表示兩種結(jié)構(gòu)。
分配內(nèi)存時:從"空閑區(qū)表"中找出一項能滿足申請空間的記錄,然后分割該項,如果分割出剩余空間,則將剩余空間重新放入"空閑區(qū)表"中,同時產(chǎn)生一個"已分配區(qū)記錄項",該記錄的長度為申請的空間大小,起始地址為分割的"空閑區(qū)"項的起始地址。并將該記錄插入到"已分配區(qū)表"中。
回收作業(yè)內(nèi)存時:刪除該作業(yè)在"已分配區(qū)表"中的記錄項,并按該項的地址和長度創(chuàng)建一個"空閑區(qū)"記錄,遍歷"空閑區(qū)表",如果存在上邊界相鄰或者下邊界相鄰的記錄項,則合并兩者(無相鄰區(qū)塊,不需要做任何操作),最后將該記錄插入到"空閑區(qū)表"中,并使之滿足降序條件。
空閑區(qū)表數(shù)據(jù)結(jié)構(gòu):
//空閑區(qū)表struct free_link{ int saddr;//起始地址 int len;//長度 int flag;//標(biāo)志 struct free_link *next;};已分配區(qū)表數(shù)據(jù)結(jié)構(gòu)://已分配區(qū)表struct alloc_link{ int saddr;//起始地址 int len;//長度 int work;//作業(yè)名 struct alloc_link *next;};最壞適應(yīng)分配算法:空閑區(qū)表中每個記錄項按照長度遞減的順序排列,當(dāng)需要分配空間時,只需要從表中取出第一項,然后為任務(wù)分割空間即可,如果分割后有剩余空間則將剩余部分再次插入空閑區(qū)表中,并重新調(diào)整表中記錄項,使得滿足按照長度遞減順序。
分配內(nèi)存流程圖:
內(nèi)存回收流程圖:
在回收內(nèi)存時,會涉及到回收的空閑塊可能會與"空閑區(qū)表"中的某個記錄項上邊界相鄰或者下邊界相鄰或者上下邊界都有相鄰的空閑塊,這時候就需要合并要回收的記錄塊和已有的空閑塊,本例中采用的方式是:先根據(jù)要回收的"已分配區(qū)表"中的記錄項A,生成一個地址和長度相同的空閑塊記錄B,然后遍歷"空閑區(qū)塊表",發(fā)現(xiàn)有上邊界相鄰的記錄項C,則修改B的起始地址為C記錄中的起始地址,長度為B塊的長度+C塊的長度,然后從鏈表中刪除記錄C,繼續(xù)遍歷,如果發(fā)現(xiàn)有下邊界相鄰的記錄D,則再修改C的長度為原有長度+D的記錄長度,從鏈表中再把記錄D刪除,這樣直到遍歷到鏈表尾部。此時4中不同情況都已經(jīng)包含(上邊界相鄰、下邊界相鄰,上下邊界同時相鄰、無相鄰),只需要將記錄B插入到"空閑區(qū)表"中即可。
空閑塊合并核心代碼:
//空閑塊頭指針 fp = free_head; while(fp->next != NULL) { //上邊界相同 if((fp->next->saddr + fp->next->len) == fitem->saddr) { //上邊界與待回收的空間邊界進(jìn)行合并 fitem->saddr = fp->next->saddr; fitem->len = fp->next->len + fitem->len; //釋放原有空閑塊的內(nèi)存 tmp_item = fp->next; fp->next = tmp_item->next; tmp_item->next = NULL; free(tmp_item); tmp_item = NULL; } if((fitem->saddr + fitem->len) == fp->next->saddr) { //下邊界與待回收的空間邊界合并 fitem->len = fitem->len + fp->next->len; //釋放原有空閑塊內(nèi)存 tmp_item = fp->next; fp->next = tmp_item->next; tmp_item->next = NULL; free(tmp_item); tmp_item = NULL; } //如果已經(jīng)遍歷到鏈尾則跳出 if(fp->next == NULL) { break; } fp = fp->next; } //重新調(diào)整空閑區(qū)表,按空間遞減順序排列 fp = free_head; while(fp->next != NULL) { if(fp->next->len <= fitem->len) { break; } fp = fp->next; } fitem->next = fp->next; fp->next = fitem;空閑塊合并示意圖如下:
空閑區(qū)表和已分配區(qū)表在分配和回收過程中變化效果圖:
代碼示例
|
新聞熱點(diǎn)
疑難解答