生活随笔
收集整理的這篇文章主要介紹了
内存管理 三
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
假設(shè)系統(tǒng)的可利用內(nèi)存空間容量為2m個字(地址從0到2m-1),則在開始運行時,整個內(nèi)存區(qū)是一個大小為2m的空閑塊,在運行了一段時間之后,被分隔成若干占用塊和空閑塊。為了在分配時查找方便起見,我們將所有大小相同的空閑塊建于一張子表中。每個子表是一個雙重鏈表,這樣的鏈表可能有m+1個,將這m+1個表頭指針用向量結(jié)構(gòu)組織成一個表,這就是伙伴系統(tǒng)中的可利用空間表,如圖所示:
分配算法:?
?? ? ? 當(dāng)用戶提出大小為n的內(nèi)存請求時,首先在可利用表上尋找結(jié)點大小與n相匹配的子表,若此子表非空,則將子表中任意一個結(jié)點分配之即可;若此子表為空,則需從結(jié)點更大的非空子表中去查找,直至找到一個空閑塊,則將其中一部分分配給用戶,而將剩余部分插入相應(yīng)的子表中。
? ? ? ?若2k-1?< n ≤ 2k-1,又第k+1個子表不空,則只要刪除此鏈表中第一個結(jié)點并分配給用戶即可;若 2k-2?< n ≤ 2k-1-1,此時由于結(jié)點大小為2k-1?的子表為空,則需從結(jié)點大小為2k?的子表中取出一塊,將其中一半分配給用戶,剩余的一半作為一個新結(jié)點插入在結(jié)點大小為2k-1的子表中,若2k-i-1?< n ≤ 2k-i-1(i為小于是的整數(shù)),并且所有結(jié)點小于2k的子表均為空,則同樣需從結(jié)點大小為2k的子表中取出一塊,將其中2k-i的一小部分分配給用戶,剩余部分分割成若干個結(jié)點分別插入在結(jié)點大小為2k-1?、 2k-2?、…、 2k-i的子表中。
回收算法:
? ? ? ? 在用戶釋放不再使用的占用塊時,系統(tǒng)需將這新的空閑塊插入到可利用空間表中去。這里,同樣有一個地址相鄰的空閑塊歸并成大塊的問題。但是在伙伴系統(tǒng)中僅考慮互為“伙伴”的兩個空閑塊的歸并。
? ? ? ? 何謂“伙伴”?如前所述,在分配時經(jīng)常需要將一個大的空閑塊分裂成兩個大小相等的存儲區(qū),這兩個由同一大塊分裂出來的小塊就稱之“互為伙伴”。例如:假設(shè)p為大小為pow(2,k)的空閑塊的初始地址,且p MOD pow(2,k+1)=0,則初始地址為p和p+pow(2,k)的兩個空閑塊互為伙伴。在伙伴系統(tǒng)中回收空閑塊時,只當(dāng)其伙伴為空閑塊時才歸并成大塊。也就是說,若有兩個空閑塊,即使大小相同且地址相鄰,但不是由同一大塊分裂出來的,也不歸并在一起。
? ? ? ? 由此,在回收空閑塊時,應(yīng)首先判別其伙伴是否為空閑塊,若否,則只要將釋放的空閑塊簡單插入在相應(yīng)子表中即可;若是,則需在相應(yīng)子表中找到其伙伴并刪除之,然后再判別合并后的空閑塊的伙伴是否是空閑塊。依此重復(fù),直到歸并所得空閑塊的伙伴不是空閑塊時,再插入到相應(yīng)的子表中去。
代碼如下(只用了單鏈表):
[cpp]?view plaincopy
#include?<stdio.h>?? #include?<stdlib.h>?? #include?<time.h>?? ?? #define?MIN_MOMORY_SIZE?536870912???//隨機產(chǎn)生的最小內(nèi)存空間:512M?(最大為1G)??? #define?INDEX_SIZE?30???????????????//哈希索引表大小??? #define?WORKTIME?1500???????????????//系統(tǒng)工作時間??? #define?MAX_REQ_SIZE?268435456??????//申請空閑內(nèi)存分配的最大容量:256M??? #define?MIN_DUE?30??????????????????//使用內(nèi)存塊的最短時間?? #define?MAX_DUE?90??????????????????//使用內(nèi)存塊的最長時間?? #define?OCCUPY_INTERVAL?60??????????//每次分配的最大間隔??? #define?USED?1??????????????????????//內(nèi)存塊被使用??? #define?UNUSED?0????????????????????//內(nèi)存塊未被使用?? ?? ?? typedef?struct?buddy_node?{?? ????int?flag;????????????????????????? ????int?base;????????????????????????? ????int?occupy;??????????????????????? ????int?fragment;????????????????????? ????int?duetime;?????????????????????? ????struct?buddy_node?*nextPtr;??????? }?Buddy,?*BuddyPtr;?? ?? ?? typedef?struct?hash_table?{?? ????int?nodesize;?? ????BuddyPtr?headPtr;?? }?IndexTable;?? ?? IndexTable?table[INDEX_SIZE];?? int?ready?=?0;????????????????? int?availSpace;???????????????? int?totalFragment?=?0;????????? ?? ?? int?get_size?(int?k)?? {?? ????int?i,?nodesize?=?1;?? ?????? ????for?(i?=?0;?i?<?k;?i?++)?? ????????nodesize?*=?2;?? ?? ????return?nodesize;?? }?? ?? ?? void?ini_index?(void)?? {?? ????int?i;?? ?????? ????for?(i?=?0;?i?<?INDEX_SIZE;?i?++)?{?? ????????table[i].nodesize?=?get_size(i);?? ????????table[i].headPtr?=?NULL;?? ????}??? }?? ?? ?? void?int_system?(int?memory_size)?? {?? ????int?i,?addr?=?0;?? ????int?left?=?memory_size;?? ????BuddyPtr?newnodePtr?=?NULL;?? ??????? ?????? ????availSpace?=?memory_size;??? ????totalFragment?=?0;?? ?????? ?????? ????for?(i?=?INDEX_SIZE-1;?left?>?0;?i?--)?{?? ????????if?(left?/?table[i].nodesize?==?1)?{?? ????????????newnodePtr?=?(BuddyPtr)?malloc?(sizeof?(Buddy));?? ????????????newnodePtr->flag?=?UNUSED;?? ????????????newnodePtr->base?=?addr;?? ????????????newnodePtr->occupy?=?0;??? ????????????newnodePtr->fragment?=?0;?? ????????????newnodePtr->duetime?=?0;?? ????????????newnodePtr->nextPtr?=?NULL;?? ????????????table[i].headPtr?=?newnodePtr;?? ????????????addr?+=?table[i].nodesize;?? ????????????left?-=?table[i].nodesize;?? ????????}?? ????}??? }?? ?? ?? void?free_system?(void)?? {?? ????int?i;?? ????BuddyPtr?tempPtr?=?NULL,?tofreePtr?=?NULL;?? ??????? ????for?(i?=?0;?i?<?INDEX_SIZE;?i?++)?{?? ????????if?(table[i].headPtr)?{?? ????????????tempPtr?=?table[i].headPtr;?? ????????????table[i].headPtr?=?NULL;?? ?????????????? ????????????while?(tempPtr)?{?? ????????????????tofreePtr?=?tempPtr;?? ????????????????tempPtr?=?tempPtr->nextPtr;?? ????????????????free?(tofreePtr);?? ????????????}?? ????????}?? ????}?? }?? ?? ?? void?insert_node?(int?i,?int?inbase,?int?f,?int?occ,?int?frag,?int?d)?? {?? ????BuddyPtr?newnodePtr?=?NULL,?prePtr?=?NULL,?curPtr?=?NULL;?? ?????? ????newnodePtr?=?(BuddyPtr)?malloc?(sizeof?(Buddy));?? ????newnodePtr->base?=?inbase;?? ????newnodePtr->flag?=?f;?? ????newnodePtr->occupy?=?occ;??? ????newnodePtr->fragment?=?frag;?? ????newnodePtr->duetime?=?d;?? ????newnodePtr->nextPtr?=?NULL;??? ????if?(table[i].headPtr?==?NULL)?? ????????table[i].headPtr?=?newnodePtr;?? ????else?{?? ????????curPtr?=?table[i].headPtr;?? ????????prePtr?=?NULL;?? ?????????? ????????while?(curPtr?&&?curPtr->base?<?inbase)?{?? ????????????prePtr?=?curPtr;?? ????????????curPtr?=?curPtr->nextPtr;???? ????????}?? ????????if?(prePtr?==?NULL)?{???????????? ????????????newnodePtr->nextPtr?=?curPtr;?? ????????????table[i].headPtr?=?newnodePtr;?? ????????}?? ????????else?if?(curPtr?==?NULL)?{??????? ????????????prePtr->nextPtr?=?newnodePtr;?? ????????}?? ????????else?{??????????????????????????? ????????????prePtr->nextPtr?=?newnodePtr;?? ????????????newnodePtr->nextPtr?=?curPtr;?? ????????}??? ????}?? }?? ?? ?? int?delete_node?(int?i,?BuddyPtr?delPtr)?? {?? ????BuddyPtr?prePtr?=?NULL,?curPtr?=?NULL;?? ????int?basehold?=?delPtr->base;?? ?????? ????curPtr?=?table[i].headPtr;?? ????while?(curPtr?!=?delPtr)?{???? ????????prePtr?=?curPtr;?? ????????curPtr?=?curPtr->nextPtr;???? ????}?? ????if?(prePtr?==?NULL)??????????? ????????table[i].headPtr?=?curPtr->nextPtr;?? ????else?????????????????????????? ????????prePtr->nextPtr?=?curPtr->nextPtr;?? ?? ????free?(curPtr);???????????????? ?????? ????return?basehold;?????????????? }??? ?? ?? void?buddy_allocate?(int?time_slice)?? {?? ????int?i,?j,?size,?due;?? ????int?state?=?0;???????????????? ????int?inbase,?basehold;?? ????BuddyPtr?curPtr?=?NULL;?? ?????? ????if?(ready?==?time_slice)?{???? ????????printf?("Time?%d:",?time_slice);?? ????????size?=?1?+?rand?()?%?MAX_REQ_SIZE;?????????????? ????????due?=?MIN_DUE?+?rand?()%(MAX_DUE?-?MIN_DUE);???? ?????????? ????????if?(availSpace?>?size)?{?? ?????????????? ????????????for?(i?=?0;?(i?<?INDEX_SIZE)?&&?(state?==?0);?i?++)?{?? ?????????????????? ????????????????if?(table[i].nodesize?>=?size?&&?table[i].headPtr)?{?? ????????????????????curPtr?=?table[i].headPtr;?? ?????????????????????? ????????????????????while?(curPtr?&&?(state?==?0))?{?? ?????????????????????????? ????????????????????????if?(curPtr->flag?==?UNUSED)?{?? ?????????????????????????????? ????????????????????????????if?(table[i].nodesize?/?size?==?1)?{?? ?????????????????????????????????? ????????????????????????????????curPtr->flag?=?USED;?? ????????????????????????????????curPtr->occupy?=?size;?? ????????????????????????????????curPtr->fragment?=?table[i].nodesize?-?size;?? ????????????????????????????????curPtr->duetime?=?due?+?ready;?? ?????????????????????????????????? ????????????????????????????????availSpace?-=?table[i].nodesize;?? ????????????????????????????????totalFragment?+=?curPtr->fragment;?? ????????????????????????????????state?=?1;?? ????????????????????????????????break;?? ????????????????????????????}?? ?????????????????????????????? ????????????????????????????else?{?? ????????????????????????????????basehold?=?delete_node?(i,?curPtr);?? ????????????????????????????????inbase?=?basehold?+?table[i].nodesize;?? ????????????????????????????????j?=?i;?? ?????????????????????????????????? ????????????????????????????????do?{?? ????????????????????????????????????j?--;?? ????????????????????????????????????inbase?-=?table[j].nodesize;????? ????????????????????????????????????insert_node?(j,?inbase,?UNUSED,?0,?0,?0);?? ????????????????????????????????????printf?("A?block?cut?takes?place\n");?? ????????????????????????????????}?while?(table[j].nodesize?/?size?>?1);?? ?????????????????????????????????? ????????????????????????????????insert_node?(j,?basehold,?USED,?size,?table[j].nodesize?-?size,?due?+?ready);?? ?????????????????????????????????? ????????????????????????????????availSpace?-=?table[j].nodesize;?? ????????????????????????????????totalFragment?+=?table[j].nodesize?-?size;?? ????????????????????????????????state?=?1;?? ????????????????????????????}?? ????????????????????????}?? ?????????????????????????? ????????????????????????else?? ????????????????????????????curPtr?=?curPtr->nextPtr;?? ????????????????????}?? ????????????????}?????????????? ????????????}?? ????????????printf?("Allocated?%d,Fragment?%d,Due?%d\n",?size,?totalFragment,?ready+due);?? ????????}?? ?????????????? ????????else?if?((availSpace?<?size)?&&?((availSpace?+?totalFragment)?>=?size))?? ????????????printf?("Allocation?failed?because?of?fragment!\n");?? ????????else?? ????????????printf?("Allocation?failed?because?of?no?enough?unused?space!\n");?? ?????????????? ????????ready?+=?(1?+?rand()?%?OCCUPY_INTERVAL);???? ????}?? }?? ?? ?? void?buddy_retrieve?(int?time_slice)?? {?? ????int?i,?basehold,?dif;?? ????int?f?=?0;?? ????int?Modnext=0;?? ????BuddyPtr?curPtr?=?NULL,?todelPtr?=?NULL;??? ?????? ?????? ????for?(i?=?0;?i?<?INDEX_SIZE;?i?++)?{?? ????????if?(table[i].headPtr)?{?? ????????????curPtr?=?table[i].headPtr;?? ????????????while?(curPtr)?{?? ????????????????if?((curPtr->flag?==?USED)?&&?(curPtr->duetime?==?time_slice))?{?? ?????????????????????? ????????????????????availSpace?+=?table[i].nodesize;?? ????????????????????totalFragment?-=?curPtr->fragment;?? ?????????????????????? ????????????????????curPtr->flag?=?UNUSED;?? ????????????????????curPtr->occupy?=?0;??? ????????????????????curPtr->fragment?=?0;?? ????????????????????curPtr->duetime?=?0;?? ????????????????????printf?("Time?%d:Retrieve?%d,Fragment?%d\n",?time_slice,?table[i].nodesize,?totalFragment);?? ????????????????}?? ????????????????curPtr?=?curPtr->nextPtr;?? ????????????}?? ????????}?? ????}?? ?????? ?????? ????for?(i?=?0;?i?<?INDEX_SIZE;?i?++)?{?? ????????if?(table[i].headPtr)?{?????????????? ????????????curPtr?=?table[i].headPtr;?? ????????????while?(curPtr?&&?curPtr->nextPtr)?{?? ?????????????????? ????????????????if?(curPtr->flag?==?UNUSED?&&?(curPtr->nextPtr)->flag?==?UNUSED)?{?? ????????????????????dif?=?(curPtr->nextPtr)->base?-?curPtr->base;?? ????????????????????Modnext?=?((int)(curPtr->nextPtr->base))%(2*table[i].nodesize);?? ????????????????????if?((dif?==?table[i].nodesize)&&(Modnext==0))?{?? ?????????????????????????? ????????????????????????todelPtr?=?curPtr;?? ????????????????????????curPtr?=?curPtr->nextPtr;?? ????????????????????????basehold?=?delete_node?(i,?todelPtr);?? ????????????????????????todelPtr?=?curPtr;?? ????????????????????????curPtr?=?curPtr->nextPtr;?? ????????????????????????delete_node?(i,?todelPtr);?? ????????????????????????insert_node?(i+1,?basehold,?UNUSED,?0,?0,?0);?? ????????????????????????printf?("Two?blocks?merge\n");?? ????????????????????}?? ????????????????????else?? ????????????????????????curPtr?=?curPtr->nextPtr;?? ????????????????}?? ????????????????else?? ????????????????????curPtr?=?curPtr->nextPtr;?? ????????????}?? ????????}?? ????}?? }?? ?? ?? void?buddy_system?(void)?? {?? ????int?time_slice?=?0;?? ?????? ?????? ????for?(;?time_slice?<?WORKTIME;?time_slice?++)?{?? ????????buddy_allocate?(time_slice);??????????? ????????buddy_retrieve?(time_slice);??????????? ????}?? }?? ?? ?? int?main(int?argc,?char?*argv[])?? {?? ????int?memory_size;?? ?????? ????ini_index?();????????????????? ????srand?(time?(NULL));?????????? ?????? ????memory_size?=?MIN_MOMORY_SIZE?+?rand()?%?MIN_MOMORY_SIZE;??? ????printf?("The?size?of?memory?is:%d\n",?memory_size);?? ?????? ????int_system?(memory_size);????? ?????? ????buddy_system?();?????????????? ????printf?("Time?%d:System?execution?stops?and?the?spaces?are?all?freed.\n",?WORKTIME);?? ?????? ????free_system?();??????????????? ?????? ????return?0;?? } ?
總結(jié)
以上是生活随笔為你收集整理的内存管理 三的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。