日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

内存管理 三

發(fā)布時間:2024/4/18 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内存管理 三 小編覺得挺不錯的,現(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)存塊未被使用??
  • ??
  • //內(nèi)存塊鏈表結(jié)點結(jié)構(gòu)???
  • typedef?struct?buddy_node?{??
  • ????int?flag;???????????????????????//標(biāo)記空間是否被使用??
  • ????int?base;???????????????????????//本塊兒內(nèi)存的基地址???
  • ????int?occupy;?????????????????????//實際使用空間大小???
  • ????int?fragment;???????????????????//碎片大小???
  • ????int?duetime;????????????????????//使用時間??
  • ????struct?buddy_node?*nextPtr;?????//指向下一個結(jié)點???
  • }?Buddy,?*BuddyPtr;??
  • ??
  • //哈希索引表結(jié)構(gòu)???
  • typedef?struct?hash_table?{??
  • ????int?nodesize;??
  • ????BuddyPtr?headPtr;??
  • }?IndexTable;??
  • ??
  • IndexTable?table[INDEX_SIZE];//使用哈希表管理伙伴系統(tǒng)???
  • int?ready?=?0;???????????????//需要分配內(nèi)存的時刻???
  • int?availSpace;??????????????//可分配空間大小???
  • int?totalFragment?=?0;???????//總碎片大小???
  • ??
  • //函數(shù):根據(jù)k的值計算哈希表項鏈接的內(nèi)存塊的大小??
  • int?get_size?(int?k)??
  • {??
  • ????int?i,?nodesize?=?1;??
  • ??????
  • ????for?(i?=?0;?i?<?k;?i?++)??
  • ????????nodesize?*=?2;??
  • ??
  • ????return?nodesize;??
  • }??
  • ??
  • //函數(shù):初始化哈希索引表???
  • void?ini_index?(void)??
  • {??
  • ????int?i;??
  • ??????
  • ????for?(i?=?0;?i?<?INDEX_SIZE;?i?++)?{??
  • ????????table[i].nodesize?=?get_size(i);??
  • ????????table[i].headPtr?=?NULL;??
  • ????}???
  • }??
  • ??
  • //函數(shù):初始化伙伴系統(tǒng)??
  • void?int_system?(int?memory_size)??
  • {??
  • ????int?i,?addr?=?0;??
  • ????int?left?=?memory_size;??
  • ????BuddyPtr?newnodePtr?=?NULL;??
  • ???????
  • ????//初始化可分配空間大小和碎片大小???
  • ????availSpace?=?memory_size;???
  • ????totalFragment?=?0;??
  • ??????
  • ????//將內(nèi)存分割成盡量大的2倍數(shù)的空閑塊并插入到相應(yīng)的索引表項中??
  • ????for?(i?=?INDEX_SIZE-1;?left?>?0;?i?--)?{??
  • ????????if?(left?/?table[i].nodesize?==?1)?{??
  • ????????????newnodePtr?=?(BuddyPtr)?malloc?(sizeof?(Buddy));//分配結(jié)點???
  • ????????????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;??
  • ????????}??
  • ????}???
  • }??
  • ??
  • //函數(shù):程序運行結(jié)束后釋放所有結(jié)點??
  • 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;??
  • ????????????//依次釋放所有結(jié)點??
  • ????????????while?(tempPtr)?{??
  • ????????????????tofreePtr?=?tempPtr;??
  • ????????????????tempPtr?=?tempPtr->nextPtr;??
  • ????????????????free?(tofreePtr);??
  • ????????????}??
  • ????????}??
  • ????}??
  • }??
  • ??
  • //函數(shù):添加結(jié)點(形參為內(nèi)存塊結(jié)點的信息)???
  • 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));//分配結(jié)點??
  • ????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;??
  • ????????//按地址順序插入內(nèi)存塊???
  • ????????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;??
  • ????????}???
  • ????}??
  • }??
  • ??
  • //函數(shù):刪除結(jié)點??
  • int?delete_node?(int?i,?BuddyPtr?delPtr)??
  • {??
  • ????BuddyPtr?prePtr?=?NULL,?curPtr?=?NULL;??
  • ????int?basehold?=?delPtr->base;??
  • ??????
  • ????curPtr?=?table[i].headPtr;??
  • ????while?(curPtr?!=?delPtr)?{??//尋找要刪除的結(jié)點的位置???
  • ????????prePtr?=?curPtr;??
  • ????????curPtr?=?curPtr->nextPtr;????
  • ????}??
  • ????if?(prePtr?==?NULL)?????????//要刪除的結(jié)點在最前???
  • ????????table[i].headPtr?=?curPtr->nextPtr;??
  • ????else????????????????????????//要刪除的結(jié)點不在鏈表的最前???
  • ????????prePtr->nextPtr?=?curPtr->nextPtr;??
  • ??
  • ????free?(curPtr);??????????????//釋放結(jié)點???
  • ??????
  • ????return?basehold;????????????//返回刪除的內(nèi)存塊結(jié)點的基地址???
  • }???
  • ??
  • //函數(shù):伙伴系統(tǒng)的分配算法???
  • void?buddy_allocate?(int?time_slice)??
  • {??
  • ????int?i,?j,?size,?due;??
  • ????int?state?=?0;??????????????//分配狀態(tài):0為未分配,1為已分配???
  • ????int?inbase,?basehold;??
  • ????BuddyPtr?curPtr?=?NULL;??
  • ??????
  • ????if?(ready?==?time_slice)?{??//到達(dá)分配內(nèi)存的時刻???
  • ????????printf?("Time?%d:",?time_slice);??
  • ????????size?=?1?+?rand?()?%?MAX_REQ_SIZE;????????????//申請使用內(nèi)存的大小???
  • ????????due?=?MIN_DUE?+?rand?()%(MAX_DUE?-?MIN_DUE);??//申請使用內(nèi)存的時間??
  • ??????????
  • ????????if?(availSpace?>?size)?{//在可分配空間大于申請空間時分配??
  • ????????????//依次尋找可分配的內(nèi)存塊???
  • ????????????for?(i?=?0;?(i?<?INDEX_SIZE)?&&?(state?==?0);?i?++)?{??
  • ????????????????//找到一個不小于申請大小的塊索引??
  • ????????????????if?(table[i].nodesize?>=?size?&&?table[i].headPtr)?{??
  • ????????????????????curPtr?=?table[i].headPtr;??
  • ????????????????????//遍歷相應(yīng)的循環(huán)鏈表中???
  • ????????????????????while?(curPtr?&&?(state?==?0))?{??
  • ????????????????????????//找到空閑塊??
  • ????????????????????????if?(curPtr->flag?==?UNUSED)?{??
  • ????????????????????????????//空閑塊的大小小于申請大小的2倍,分配???
  • ????????????????????????????if?(table[i].nodesize?/?size?==?1)?{??
  • ????????????????????????????????//在分配的內(nèi)存塊上設(shè)置信息???
  • ????????????????????????????????curPtr->flag?=?USED;??
  • ????????????????????????????????curPtr->occupy?=?size;??
  • ????????????????????????????????curPtr->fragment?=?table[i].nodesize?-?size;??
  • ????????????????????????????????curPtr->duetime?=?due?+?ready;??
  • ????????????????????????????????//修改可系統(tǒng)分配空間和碎片大小???
  • ????????????????????????????????availSpace?-=?table[i].nodesize;??
  • ????????????????????????????????totalFragment?+=?curPtr->fragment;??
  • ????????????????????????????????state?=?1;//標(biāo)記已分配???
  • ????????????????????????????????break;??
  • ????????????????????????????}??
  • ????????????????????????????//空閑塊的大小剛大于申請大小的2倍??
  • ????????????????????????????else?{??
  • ????????????????????????????????basehold?=?delete_node?(i,?curPtr);//刪除較大的空閑塊并保留其基地址???
  • ????????????????????????????????inbase?=?basehold?+?table[i].nodesize;??
  • ????????????????????????????????j?=?i;??
  • ????????????????????????????????//分割空閑塊???
  • ????????????????????????????????do?{??
  • ????????????????????????????????????j?--;??
  • ????????????????????????????????????inbase?-=?table[j].nodesize;???//設(shè)置要添加內(nèi)存塊結(jié)點的基地址???
  • ????????????????????????????????????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);??
  • ????????????????????????????????//修改可系統(tǒng)分配空間和碎片大小???
  • ????????????????????????????????availSpace?-=?table[j].nodesize;??
  • ????????????????????????????????totalFragment?+=?table[j].nodesize?-?size;??
  • ????????????????????????????????state?=?1;//標(biāo)記已分配???
  • ????????????????????????????}??
  • ????????????????????????}??
  • ????????????????????????//塊被占用,查看下一結(jié)點???
  • ????????????????????????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);??//下次需要分配內(nèi)存的時刻??
  • ????}??
  • }??
  • ??
  • //函數(shù):伙伴系統(tǒng)的回收算法??
  • 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))?{//需要回收???
  • ????????????????????//修改可系統(tǒng)分配空間和碎片大小???
  • ????????????????????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)?{??
  • ????????????????//將地址連續(xù)且都為空閑的塊合并后加入下一級的鏈表中???
  • ????????????????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))?{??
  • ????????????????????????//刪除兩個結(jié)點???
  • ????????????????????????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);//添加合并后的結(jié)點???
  • ????????????????????????printf?("Two?blocks?merge\n");??
  • ????????????????????}??
  • ????????????????????else??
  • ????????????????????????curPtr?=?curPtr->nextPtr;??
  • ????????????????}??
  • ????????????????else??
  • ????????????????????curPtr?=?curPtr->nextPtr;??
  • ????????????}??
  • ????????}??
  • ????}??
  • }??
  • ??
  • //函數(shù):伙伴系統(tǒng)的處理過程???
  • void?buddy_system?(void)??
  • {??
  • ????int?time_slice?=?0;??
  • ??????
  • ????//在每個時間片內(nèi)使用分配算法和回收算法???
  • ????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));????????//設(shè)置隨機數(shù)種子??
  • ????//隨機產(chǎn)生需要管理的內(nèi)存大小:512M?~?1G???
  • ????memory_size?=?MIN_MOMORY_SIZE?+?rand()?%?MIN_MOMORY_SIZE;???
  • ????printf?("The?size?of?memory?is:%d\n",?memory_size);??
  • ??????
  • ????int_system?(memory_size);???//初始化伙伴系統(tǒng)???
  • ??????
  • ????buddy_system?();????????????//伙伴系統(tǒng)的處理過程??
  • ????printf?("Time?%d:System?execution?stops?and?the?spaces?are?all?freed.\n",?WORKTIME);??
  • ??????
  • ????free_system?();?????????????//釋放所有結(jié)點???
  • ??????
  • ????return?0;??
  • } ?
  • 總結(jié)

    以上是生活随笔為你收集整理的内存管理 三的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。