生活随笔
收集整理的這篇文章主要介紹了
内存管理 一
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
今天突發(fā)奇想地想學(xué)習(xí)下內(nèi)存管理(其實(shí)是報(bào)的騰訊終端開發(fā),怕面試被問到如何實(shí)現(xiàn)內(nèi)存管理模塊)。于是找找資料,寫了段代碼,可以實(shí)現(xiàn)基于最佳適應(yīng)法和循環(huán)首次適應(yīng)法的內(nèi)存分配。
? ? 大家都知道,我們malloc的時(shí)候操作系統(tǒng)維護(hù)著一張雙鏈表記錄堆里面的空閑內(nèi)存塊情況,每個(gè)節(jié)點(diǎn)對(duì)應(yīng)一塊內(nèi)存。
? ? 最佳適應(yīng)法:分配內(nèi)存(大小為size)的時(shí)候,從表頭開始搜索,找那塊比size大的最小空閑內(nèi)存塊,進(jìn)行分配,余下的部分變成一塊空閑內(nèi)存塊插入到鏈表中
? ? 循環(huán)首次適應(yīng)法:該算法是首次適應(yīng)算法的變種。在分配內(nèi)存空間時(shí),不再每次從表頭(鏈?zhǔn)?#xff09;開始查找,而是從上次找到空閑區(qū)的下一個(gè)空閑開始查找,直到找到第一個(gè)能滿足要求的的空閑區(qū)為止,并從中劃出一塊與請(qǐng)求大小相等的內(nèi)存空間進(jìn)行分配,余下的部分變成一塊空閑內(nèi)存塊插入到鏈表中,并成為下一次分配搜索的起始內(nèi)存塊。
它們的代碼如下(我們分配內(nèi)存的單位是1KB):
[cpp]?view plaincopy
?? enum?{?ADDR?=?56000,?TOTAL?=?200000,?MAX?=?20000,?MIN?=?100,?CYCLE?=?1,?BEST?=?-1,?FULL?=?1,?FREE?=?0,?N?=?2000?};?? ?? struct?node?? {?? ????struct?node*?prev;????? ????struct?node*?next;????? ????int?number;???????????? ????int?addr;?????????????? ????int?size;?????????????? ????int?status;???????????? };?? ?? typedef?struct?node?block;?? ?? void?init?();?? int?request?();?? int?cycle?(?int?size?);?? int?best?(?int?size?);?? ? ? ? ? ? ? ? ?? ?? int?occupied?=?0,?count?=?0,?compare?=?0,?algo?=?CYCLE;?? block?*head?=?NULL,?*tail?=?NULL,?*last?=?NULL;?? ?? void?init?()?? {?? ????block?*work,?*?temp;?? ????occupied?=?0;?? ????count?=?0;????????????????? ????compare?=?0;?????? ?????? ????if?(?head?!=?NULL?)?? ????{?? ????????work?=?head->next;?? ????????while?(?work?!=?head?)?? ????????{?? ????????????temp?=?work;?? ????????????work?=?work->next;?? ????????????free(temp);?? ????????}?? ????????free(head);?? ????}?? ?????? ????head?=?(block*)malloc(sizeof(block));?? ????tail?=?(block*)malloc(sizeof(block));?? ????last?=?tail;?? ????head->prev?=?tail;?? ????head->next?=?tail;????? ????tail->prev?=?head;?? ????tail->next?=?head;?? ????head->addr?=?0;?? ????head->size?=?ADDR;?? ????head->status?=?FULL;?? ????tail->addr?=?ADDR;?? ????tail->size?=?TOTAL;?? ????tail->status?=?FREE;?? }?? ?? ?? ?? int?request?()?? {?? ????int?(*fp)(int);??????? ????int?size?=?random(MIN,MAX),?addr;?? ????if?(?algo?==?CYCLE?)?? ????{?? ????????fp?=?cycle;?? ????}?? ????else?if?(?algo?==?BEST?)?? ????{?? ????????fp?=?best;?? ????}?? ????printf("嘗試申請(qǐng)一塊大小為%dKB的內(nèi)存",size);?? ????if?(?(addr?=?(*fp)(size))?==?0?)?? ????{?? ????????printf("????內(nèi)存空間不足,分配失敗\n");?? ????????return?0;?? ????}?? ????else?? ????{?? ????????printf("????在%d位置成功分配\n",addr);?? ????????return?1;?? ????}?? }?? ?? ?? ?? int?cycle?(?int?size?)?? {?? ?????? ????block*?work?=?last,?*start?=?last;???? ????if?(?last?==?NULL?)?? ????????return?0;?? ?????? ????while?(?work->status?==?FULL?||?work->size?<?size?)?? ????{?? ????????work?=?work->next;?? ????????++compare;?? ?????????? ????????if?(?work?==?start?)?? ????????????return?0;?? ????}????? ????++compare;?? ?????? ????if?(?work->size?>?size?)?? ????{?? ????????block*?remain?=?(block*)malloc(sizeof(block));?? ????????remain->addr?=?work->addr?+?size;?? ????????remain->size?=?work->size?-?size;?? ????????remain->status?=?FREE;?? ????????last?=?remain;?? ????????work->size?=?size;?? ????????work->status?=?FULL;??????????????????? ????????remain->prev?=?work;?? ????????remain->next?=?work->next;?? ????????work->next->prev?=?remain;?? ????????work->next?=?remain;?? ????}?? ????else?? ????{?? ?????????? ????????block*?temp?=?work;?? ????????work->status?=?FULL;?? ????????while?(?temp->status?==?FULL?)?? ????????{?? ????????????temp?=?temp->next;?? ????????????if?(?temp?==?work?)?? ????????????????break;?? ????????}?? ????????if?(?temp?==?work?)?? ????????{?? ????????????last?=?NULL;?? ????????}?? ????????else?? ????????{?? ????????????last?=?temp;?? ????????}?? ????}?? ????++count;?? ????occupied?+=?size;?? ????return?work->addr;?? }?? ?? int?best?(?int?size?)?? {?? ????block*?work?=?head->next,?*fit;?? ?????? ????while?(?(work->status?==?FULL?||?work->size?<?size)?&&?work?!=?head?)?? ????{?? ????????work?=?work->next;?? ?????????? ????????++compare;?? ????}?? ????++compare;?? ?????? ????if?(?work?==?head?)?? ????????return?0;?? ?????? ????fit?=?work;?? ?????? ????while?(?work?!=?head?)?? ????{?? ????????work?=?work->next;?? ????????++compare;?? ????????if?(?work->status?==?FREE?&&?work->size?>=?size?&&?work->size?<?fit->size?)?? ????????????fit?=?work;?? ????}?? ?????? ????if?(?fit->size?>?size?)?? ????{?? ????????block*?remain?=?(block*)malloc(sizeof(block));?? ????????remain->addr?=?fit->addr?+?size;?? ????????remain->size?=?fit->size?-?size;?? ????????remain->status?=?FREE;?? ????????fit->size?=?size;?? ????????fit->status?=?FULL;???????????????????? ????????remain->prev?=?fit;?? ????????remain->next?=?fit->next;?? ????????fit->next->prev?=?remain;?? ????????fit->next?=?remain;?? ????}?? ?????? ????else?? ????{?? ????????fit->status?=?FULL;?? ????}?? ?????? ????++count;?? ?????? ????occupied?+=?size;?? ?????? ????return?fit->addr;?? }??
內(nèi)存回收:這里用于測(cè)試,我們隨機(jī)回收一塊內(nèi)存,如果內(nèi)存前后有未占用內(nèi)存,則合并。
[cpp]?view plaincopy
void?recycle?()?? {?? ????if?(?count?==?0?)?? ????{?? ????????printf("無已分配的內(nèi)存塊\n");?? ????????return;?? ????}?? ????else?? ????{?? ????????int?n?=?random(1,count);?? ????????block*?work?=?head->next,?*prev,?*next;???????? ????????do?? ????????{?? ????????????if?(?work->status?==?FREE?)?? ????????????{?? ????????????????work?=?work->next;?? ????????????????continue;?? ????????????}?? ????????????else?? ????????????{????????????? ????????????????if?(?--n?==?0?)?? ????????????????{?? ????????????????????printf("回收了位于%d的內(nèi)存塊,其大小為%dKB\n",work->addr,work->size);?? ????????????????????prev?=?work->prev;?? ????????????????????next?=?work->next;?? ????????????????????occupied?-=?work->size;?? ????????????????????if?(?prev->status?==?FREE?&&?next->status?==?FREE?)?? ????????????????????{?? ????????????????????????prev->size?+=?work->size?+?next->size;?? ????????????????????????prev->next?=?next->next;?? ????????????????????????next->next->prev?=?prev;?? ????????????????????????if?(?next?==?last?)??????????????????? ????????????????????????????last?=?prev;?????????????????? ????????????????????????free(work);?? ????????????????????????free(next);?? ????????????????????}?? ????????????????????else?if?(?prev->status?==?FREE?&&?next->status?==?FULL?)?? ????????????????????{?? ????????????????????????prev->size?+=?work->size;?? ????????????????????????prev->next?=?next;?? ????????????????????????next->prev?=?prev;?? ????????????????????????free(work);?? ????????????????????}?? ????????????????????else?if?(?prev->status?==?FULL?&&?next->status?==?FREE?)?? ????????????????????{?? ????????????????????????work->size?+=?next->size;?? ????????????????????????work->status?=?FREE;?? ????????????????????????work->next?=?next->next;?? ????????????????????????next->next->prev?=?work;?? ????????????????????????if?(?next?==?last?)?? ????????????????????????????last?=?work;?? ????????????????????????free(next);?? ????????????????????}?? ????????????????????else?? ????????????????????{?? ????????????????????????work->status?=?FREE;?? ????????????????????}?? ????????????????????--count;?????????????????????? ????????????????????return;?? ????????????????}????? ????????????????else?? ????????????????{?? ????????????????????work?=?work->next;?? ????????????????}????????? ????????????}?? ????????}?? ????????while?(?n?>?0?);?? ????}?? }??
? ? 作為一個(gè)剛接觸內(nèi)存管理的菜鳥,滋生如下問題,望牛人指教:
? ? 1. 我覺得在自己的項(xiàng)目里添加一個(gè)內(nèi)存模塊是不是整個(gè)項(xiàng)目的內(nèi)存分配要合理一些(先malloc一塊大內(nèi)存,再對(duì)其管理)?
? ? ?2.內(nèi)存分配會(huì)產(chǎn)生碎片,那對(duì)于碎片如何回收呢,如果我規(guī)定分配的內(nèi)存塊大小都必須是2k的倍數(shù)(2k,4k,8k),對(duì)于每個(gè)請(qǐng)求的內(nèi)存分配給它最相近的內(nèi)存大小(如請(qǐng)求3k,分配4k的內(nèi)存塊給它),產(chǎn)生的內(nèi)存碎片是不是會(huì)少很多?
? ? 3.如果我的項(xiàng)目最多只需要分配幾個(gè)不同大小的內(nèi)存塊(如3個(gè)12k,一個(gè)43k,2個(gè)6k),是不是先malloc(3*12+42+2*6)k內(nèi)存,再分割成3個(gè)12k,一個(gè)43k,2個(gè)6k的內(nèi)存塊,然后每次要分配的時(shí)候去FIT,是不是分配的效率會(huì)提升很多?
總結(jié)
以上是生活随笔為你收集整理的内存管理 一的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。