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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

内存管理 一

發(fā)布時(shí)間:2024/4/18 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内存管理 一 小編覺得挺不錯(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
  • //內(nèi)存塊首地址為56000(假定內(nèi)存空間的低址部分56MB(即0~56M-1)作為系統(tǒng)區(qū)和不參與分配過程),總大小為200000??
  • enum?{?ADDR?=?56000,?TOTAL?=?200000,?MAX?=?20000,?MIN?=?100,?CYCLE?=?1,?BEST?=?-1,?FULL?=?1,?FREE?=?0,?N?=?2000?};??
  • ??
  • struct?node??
  • {??
  • ????struct?node*?prev;???//前一個(gè)內(nèi)存塊??
  • ????struct?node*?next;???//后一個(gè)內(nèi)存塊??
  • ????int?number;??????????//序列號(hào)??
  • ????int?addr;????????????//首地址??
  • ????int?size;????????????//大小??
  • ????int?status;??????????//狀態(tài):空閑/使用??
  • };??
  • ??
  • typedef?struct?node?block;??
  • ??
  • void?init?();??
  • int?request?();??
  • int?cycle?(?int?size?);??
  • int?best?(?int?size?);??
  • /*occupied:占用的內(nèi)存總量?
  • ??count:占用的內(nèi)存塊數(shù)目?
  • ??compare:比較次數(shù)?
  • ??algo:算法?
  • ??head:表頭?
  • ??tail:初始時(shí)的表尾?
  • ??last:循環(huán)首次適應(yīng)算法中下一次搜索的起始內(nèi)存塊?
  • */??
  • ??
  • 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;??
  • }??
  • ??
  • ??
  • //請(qǐng)求分配內(nèi)存??
  • 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;??
  • ????}??
  • }??
  • ??
  • ??
  • //循環(huán)首次適應(yīng)算法??
  • int?cycle?(?int?size?)??
  • {??
  • ????//從上一次空閑內(nèi)存塊(last指向)開始搜索??
  • ????block*?work?=?last,?*start?=?last;????
  • ????if?(?last?==?NULL?)??
  • ????????return?0;??
  • ????//沿著鏈表方向搜索,找到一塊大小滿足要求的空閑內(nèi)存塊作為待分配內(nèi)存塊??
  • ????while?(?work->status?==?FULL?||?work->size?<?size?)??
  • ????{??
  • ????????work?=?work->next;??
  • ????????++compare;??
  • ????????//遍歷完整個(gè)鏈表還沒找到,返回0??
  • ????????if?(?work?==?start?)??
  • ????????????return?0;??
  • ????}?????
  • ????++compare;??
  • ????//大小超過要分配的內(nèi)存,當(dāng)前內(nèi)存塊被分配,多出來的一部分變成空閑內(nèi)存塊插入到被分配的內(nèi)存塊之后,讓last指向它??
  • ????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??
  • ????{??
  • ????????//大小剛好,則last指向下一個(gè)空閑內(nèi)存塊??
  • ????????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;??
  • }??
  • //最佳適應(yīng)算法??
  • int?best?(?int?size?)??
  • {??
  • ????block*?work?=?head->next,?*fit;??
  • ????//沿著鏈表頭尋找未占用的,大小大于當(dāng)前申請(qǐng)內(nèi)存的內(nèi)存塊??
  • ????while?(?(work->status?==?FULL?||?work->size?<?size)?&&?work?!=?head?)??
  • ????{??
  • ????????work?=?work->next;??
  • ????????//每次判斷,比較次數(shù)+1??
  • ????????++compare;??
  • ????}??
  • ????++compare;??
  • ????//無法找到滿足要求的內(nèi)存塊,返回0??
  • ????if?(?work?==?head?)??
  • ????????return?0;??
  • ????//當(dāng)前內(nèi)存塊大小滿足要求??
  • ????fit?=?work;??
  • ????//尋找大小滿足要求的最小空閑內(nèi)存塊??
  • ????while?(?work?!=?head?)??
  • ????{??
  • ????????work?=?work->next;??
  • ????????++compare;??
  • ????????if?(?work->status?==?FREE?&&?work->size?>=?size?&&?work->size?<?fit->size?)??
  • ????????????fit?=?work;??
  • ????}??
  • ????//大小超過要分配的內(nèi)存,當(dāng)前內(nèi)存塊被分配,多出來的一部分變成空閑內(nèi)存塊插入到被分配的內(nèi)存塊之后??
  • ????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;??
  • ????}??
  • ????//大小正好,只改變當(dāng)前內(nèi)存塊狀態(tài)??
  • ????else??
  • ????{??
  • ????????fit->status?=?FULL;??
  • ????}??
  • ????//占用內(nèi)存塊數(shù)目+1??
  • ????++count;??
  • ????//占用內(nèi)存塊總大小增加??
  • ????occupied?+=?size;??
  • ????//返回申請(qǐng)到的內(nèi)存首地址??
  • ????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ò),歡迎將生活随笔推薦給好友。