1).考慮到小型區塊所可能形成的內存破碎問題,設計了雙層級配置器. 設計
當配置區塊超過128bytes時,調用第一層級配置器,第一層級配置器直接使用malloc()和free(). 指針
當配置區塊小於128bytes時,調用第二層級配置器,採用複雜的memory pool整理方式,下降額外開銷. 遞歸
2).內存池管理方式是每次配置一大塊內存,並維護對應之自由鏈表. 內存
如有相同大小的內存分配,就直接從自由鏈表中分配內存塊. 源碼
若內存釋放時,則由配置器回收到自由鏈表中. io
第二級配置器會主動將任何小額區塊的內存需求量調至8的倍數. 變量
3).自由鏈表(free-list)節點的結構以下: 配置
利用union的特性,從第一字段觀之,obj可被視爲一個指針,指向相同形式的另外一個obj. nio
從第二字段觀之,obj可被視爲一個指針,指向實際區塊. im
一物二用,不會爲了維護鏈表所必須的指針而形成內存的一種浪費.
具體代碼實現,請參考STL源碼.下面附幾張圖說明.
第一級配置器與第二級配置器之間的關係:
第二級配置器分配內存時,自由鏈表變化示意圖:
第二級配置器釋放內存時,自由鏈表變化示意圖:
第二級配置器分配內存時,其具體步驟以下:
1).判斷內存塊大小,是否大於128bytes,若大於,則調用第一級配置器.若小於,進行步驟2).
2).從16個自由鏈表中,根據內存塊大小選擇合適的自由鏈表.
3).判斷自由鏈表是否爲空,若爲空,則從新真充自由鏈表,不然,進行步驟4).
4).調整當前自由鏈表指向一塊內存塊,並返回當前的內存塊.(相似於鏈表的刪除操做)
第二級配置器釋放內存時,其具體步驟以下:
1).判斷內存塊大小,是否大於128bytes,若大於,則調用第一級配置器.若小於,進行步驟2).
2).從16個自由鏈表中,根據內存塊大小選擇合適的自由鏈表.
3).調整當前自由鏈表回收當前的內存塊.(相似於鏈表的插入操做)
內存池的實際操做結果示意圖:
內存池管理:
1).三個變量來標識內存池的使用狀況和大小,start_free,end_free,heap_size.
2).從內存池中取空間給自由鏈表時,主要分三種狀況進行.
a).內存池剩餘空間徹底知足需求量,則直接修改start_free的值,返回對應的區塊.
b).內存池剩餘空間不能徹底知足需求量,但足夠供應一個(含)以上的區塊,則減小分配的區塊數目,而後分配.
c).內存池剩餘空間連一個區塊的大小都沒法提供,則利用malloc增長內存空間.
若malloc成功,則修改start_free,end_free,heap_size,而後遞歸調用自身,從新分配區塊.
若malloc不成功,則尋找自由鏈表中,看是否存在足夠大的區塊.
若存在,則將對應區塊做爲內存池,調整start_free,end_free,遞歸調用自身,從新分配區塊.
若不存,則調用第一級配置器.