STL的記憶體優化

2021-09-23 17:25:10 字數 2193 閱讀 6363

stl記憶體管理使用二級記憶體配置器。

1、第一級配置器

第一級配置器以malloc(),free(),realloc()等c函式執行實際的記憶體配置、釋放、重新配置等操作,並且能在記憶體需求不被滿足的時候,呼叫乙個指定的函式。

一級空間配置器分配的是大於128位元組的空間

如果分配不成功,呼叫控制代碼釋放一部分記憶體

如果還不能分配成功,丟擲異常

2、第二級配置器

在stl的第二級配置器中多了一些機制,避免太多小區塊造成的記憶體碎片,小額區塊帶來的不僅是記憶體碎片,配置時還有額外的負擔。區塊越小,額外負擔所佔比例就越大。

3、分配原則

如果要分配的區塊大於128bytes,則移交給第一級配置器處理。

如果要分配的區塊小於128bytes,則以記憶體池管理(memory pool),又稱之次層配置(sub-allocation):每次配置一大塊記憶體,並維護對應的16個空閒鍊錶(free-list)。下次若有相同大小的記憶體需求,則直接從free-list中取。如果有小額區塊被釋放,則由配置器**到free-list中。

當使用者申請的空間小於128位元組時,將位元組數擴充套件到8的倍數,然後在自由鍊錶中查詢對應大小的子鍊錶

如果在自由鍊錶查詢不到或者塊數不夠,則向記憶體池進行申請,一般一次申請20塊

如果記憶體池空間足夠,則取出記憶體

如果不夠分配20塊,則分配最多的塊數給自由鍊錶,並且更新每次申請的塊數

如果一塊都無法提供,則把剩餘的記憶體掛到自由鍊錶,然後向系統heap申請空間,如果申請失敗,則看看自由鍊錶還有沒有可用的塊,如果也沒有,則最後呼叫一級空間配置器

二級記憶體池採用了16個空閒鍊錶,這裡的16個空閒鍊錶分別管理大小為8、16、24…120、128的資料塊。這裡空閒鍊錶節點的設計十分巧妙,這裡用了乙個聯合體既可以表示下乙個空閒資料塊(存在於空閒鍊錶中)的位址,也可以表示已經被使用者使用的資料塊(不存在空閒鍊錶中)的位址。

1、空間配置函式allocate

首先先要檢查申請空間的大小,如果大於128位元組就呼叫第一級配置器,小於128位元組就檢查對應的空閒鍊錶,如果該空閒鍊錶中有可用資料塊,則直接拿來用(拿取空閒鍊錶中的第乙個可用資料塊,然後把該空閒鍊錶的位址設定為該資料塊指向的下乙個位址),如果沒有可用資料塊,則呼叫refill重新填充空間。

2、空間釋放函式deallocate

首先先要檢查釋放資料塊的大小,如果大於128位元組就呼叫第一級配置器,小於128位元組則根據資料塊的大小來判斷**後的空間會被插入到哪個空閒鍊錶。

3、重新填充空閒鍊錶refill

在用allocate配置空間時,如果空閒鍊錶中沒有可用資料塊,就會呼叫refill來重新填充空間,新的空間取自記憶體池。預設取20個資料塊,如果記憶體池空間不足,那麼能取多少個節點就取多少個。

從記憶體池取空間給空閒鍊錶用是chunk_alloc的工作,首先根據end_free-start_free來判斷記憶體池中的剩餘空間是否足以調出nobjs個大小為size的資料塊出去,如果記憶體連乙個資料塊的空間都無法**,需要用malloc取堆中申請記憶體。

假如山窮水盡,整個系統的堆空間都不夠用了,malloc失敗,那麼chunk_alloc會從空閒鍊錶中找是否有大的資料塊,然後將該資料塊的空間分給記憶體池(這個資料塊會從鍊錶中去除)。

4、總結:

使用allocate向記憶體池請求size大小的記憶體空間,如果需要請求的記憶體大小大於128bytes,直接使用malloc。

如果需要的記憶體大小小於128bytes,allocate根據size找到最適合的自由鍊錶。

a. 如果鍊錶不為空,返回第乙個node,煉表頭改為第二個node。

b. 如果鍊錶為空,使用blockalloc請求分配node。

c. 如果記憶體池中有大於乙個node的空間,分配竟可能多的node(但是最多20個),將乙個node返回,其他的node新增到鍊錶中。

d. 如果記憶體池只有乙個node的空間,直接返回給使用者。

e. 若果如果連乙個node都沒有,再次向作業系統請求分配記憶體。

①分配成功,再次進行b過程。

②分配失敗,迴圈各個自由鍊錶,尋找空間。

i. 找到空間,再次進行過程b。

ii. 找不到空間,丟擲異常。

使用者呼叫deallocate釋放記憶體空間,如果要求釋放的記憶體空間大於128bytes,直接呼叫free。

否則按照其大小找到合適的自由鍊錶,並將其插入。

STL記憶體分配

stl記憶體分配 由於小型的記憶體區塊會因此記憶體分配碎片,sgi stl設計中使用了雙層級配置器,第一級配置器直接使用malloc 和free 申請記憶體大於128位元組時呼叫 第二級配置器採用記憶體池的方式來管理。stl記憶體分配器在檔案中實現,malloc alloc template和 de...

STL 記憶體管理

stl有很多種allocator,根據c 的標準,stl的allocator把物件的申請和釋放分為四個步驟 1 申請記憶體空間,對應的函式是allocator allocate 2 執行建構函式,對應的函式是allocator construct 3 執行析構函式,對應的函式是allocator d...

STL記憶體管理

linux記憶體分配管理 實現自己的malloc stl是一套非常高效的c 庫,提到記憶體管理,怎麼能少了他呢,花了近一天的時間來剖析這個。stl記憶體分配分為兩級,為什麼分為兩級,就比如你為了買一根普通的皮帶,去漢正街批發市場,別人不一定賣給你 親身經歷 只有一次性購買大量的貨才會去批發市場,商家...