本發(fā)明屬于內存管理領域,更具體地,涉及一種基于NVRAM的內存分配鏈表及內存分配方法。
背景技術:
根據(jù)Gartner技術成熟度曲線2014年到2015年的變化,大數(shù)據(jù)已經(jīng)歷膨脹期和高峰期,消失在了2015年的曲線上,這表明大數(shù)據(jù)的基本概念、關鍵技術及對其利用已得到了業(yè)界的廣泛認可,對大數(shù)據(jù)處理分析,以發(fā)現(xiàn)其中蘊含的經(jīng)濟價值,成為了業(yè)界的共識。大數(shù)據(jù)也為存儲提出了新的挑戰(zhàn),面向大數(shù)據(jù)的內存計算等新應用需要的內存容量是現(xiàn)在的1000倍。而與此同時,傳統(tǒng)的DRAM(動態(tài)隨機存取存儲器)的發(fā)展已經(jīng)遇到瓶頸:現(xiàn)有的DRAM尺寸工藝已經(jīng)達到20nm的極限,同時數(shù)據(jù)刷新所產(chǎn)生的功耗問題隨著其容量擴大變得不可忽視。
諸如PCM(相變存儲器),ReRAM(阻變式存儲器)以及STT-RAM(自旋轉移力矩存儲器)等這類新型非易失存儲器有非易失性、位可尋址、位可修改、讀延遲短、讀能耗低、無需刷新等杰出優(yōu)點,使得其很有可能作為主存的替代品。以PCM為例,其對比DRAM能耗更低,同時其非易失性和比較高的存儲密度也使得它成為理想的內存替代品。當然,PCM也有缺陷,特別是寫性能、寫功耗和壽命問題。
就內存管理和內存分配而言,近幾十年來,通用的內存分配器glibc malloc一直都是軟件的基本元素,如圖1所示,glibc malloc的空閑內存分配鏈表通過bins,也就是鏈表數(shù)據(jù)結構來管理空閑chunks,基于所管理的chunk大小不同,將bin分為fast bin、small bin、large bin和unsorted bin,在所有的bin中:fast bin在內存分配以及釋放上速度更快,fast bin記錄著大小以8字節(jié)遞增的著free chunk單鏈表,鏈表內的chunk被稱為fast chunk,大小為16~80字節(jié),每一個單鏈表內的chunk大小均相同且使用LIFO進行鏈表中chunk的插入/刪除;小于512字節(jié)的chunk被稱為small chunk,而保存small chunk的bins被稱為small bins,small bins比large bins在內存分配/釋放的速度上更快,同樣的,small bins記錄著大小以8字節(jié)遞增的free chunk雙向循環(huán)鏈表,每一個雙向循環(huán)鏈表內的chunk大小均相同且使用FIFO進行鏈表中chunk的插入/刪除,兩個相鄰的空閑chunk會被合并成一個空閑的chunk,合并消除了碎片化的影響但是減慢了釋放的速度;大于等于512字節(jié)的chunk被稱為large chunk,而保存large chunk的bins被稱為large bins。每個large bin都包括一個空閑chunk的雙向循環(huán)鏈表,但是其中的chunk大小不一定相同,以遞減的形式保存,即最大的chunk保存在最前的位置而最小的chunk保存在最后的位置。同樣,也會將兩個相連的空閑chunk合并成一個更大的空閑chunk。當small chunk和large chunk被釋放時,它們并非被添加到前面提到的各自的bin中,而是被添加到一個叫“unsorted bin”中,其包括一個用于保存空閑chunk的雙向循環(huán)鏈表,而且沒有chunk大小限制,任何大小的chunk都可以添加進來。這種途徑給予分配器重新使用最近剛釋放掉chunk的第二次機會,如此一來尋找合適bin和chunk的時間開銷就被抹掉了,因此內存的分配和釋放也會更快一點。
如今對動態(tài)內存管理的需求現(xiàn)如今也轉移到了NVRAM領域。但是glibc malloc內存分配器的內存分配鏈表設計非但不適合NVRAM,而且會加速NVRAM的磨損。
對NVRAM內存來說,使用現(xiàn)有的內存分配器存在兩個方面的缺陷:(1)內存分配策略導致NVRAM局部熱區(qū);(2)固定的從虛擬內存地址到物理地址的映射導致原地內存寫。
技術實現(xiàn)要素:
針對現(xiàn)有傳統(tǒng)技術的以上缺陷或改進需求,本發(fā)明提供了一種基于NVRAM的內存分配鏈表及內存分配方法,其目的在于Fastbins中的fast bin鏈表采用FIFO法進行鏈表中chunk的插入或刪除;Bins為每個small bin和new bin鏈表添加一個分配計數(shù)器,監(jiān)控每個bin的分配次數(shù),為超分配閾值的bin分配新的new bin降低高讀寫區(qū)域的磨損;延遲分配鏈表為重新分配的內存區(qū)域提供一個延遲時間。由此解決現(xiàn)有非易失存儲器NVRAM在內存分配時存在的磨損均衡問題,以求提升NVRAM內存的使用壽命。
為實現(xiàn)上述目的,按照本發(fā)明的一個方面,提供了一種基于NVRAM的內存分配鏈表,該內存分配鏈表包括以下部分:
Fastbins,一個數(shù)組,用于記錄所有fast bin鏈表,鏈表使用FIFO(先進先出)法進行鏈表中chunk的插入或刪除;
Bins,一個數(shù)組,用于記錄所有new bin、small bin和large bin鏈表,new bin和small bin鏈表采用FIFO法進行鏈表中chunk的插入或刪除,每個new bin和small bin鏈表都設置一個計數(shù)器,記錄各自的分配次數(shù),當分配次數(shù)到達分配閾值k時,則向系統(tǒng)空閑內存空間申請一個新的new bin,用于存放新分配的chunk,new bin的大小Nnb為
Nnb=k×Nc,
其中,Nc為新分配chunk的大??;分配閾值k的取值范圍為100<k<50000,優(yōu)選k=4096;
延遲分配鏈表,用于保存剛被用戶釋放的fast chunk、small chunk和large chunk,鏈表使用FIFO法進行鏈表中chunk的插入或刪除,每個新進入的chunk會被標記一個窗口,窗口初始大小為φ,φ的取值范圍為1KB<φ<4096KB,優(yōu)選φ=4KB;同時更新其他分配窗口的大小
Ni=Ni-δn,i=1,2,3,...,n-1,
其中,Ni表示第i個進入延遲分配鏈表的chunk的標記窗口的大??;δn是新進入延遲分配鏈表的chunk的大?。划擭1<0時,將延遲分配鏈表中最先進入的chunk取出放回到其他空閑內存分配鏈表中以待下一次分配,同時更新所有chunk進入鏈表的順序i=i-1。
進一步地,所述new bin中的chunk被用戶釋放后,若new bin的分配次數(shù)大于分配閾值,則釋放new bin所占內存空間;否則不釋放new bin所占內存空間,該chunk將被還回new bin中。
按照本發(fā)明的另一方面,提供了基于NVRAM的內存分配方法,該方法包括以下步驟:
(1)將用戶請求內存空間的大小轉換為實際需要分配的chunk空間大?。?/p>
(2)判斷chunk空間大小是否小于64B,若是則進行步驟(3);否則進行步驟(4);
(3)在Fastbins中找到一個合適的chunk;分配完成,進入步驟(7);
(4)在Bins中找到一個合適的chunk;分配完成;
(5)判斷chunk是否在small bin或large bin中,若是則進入步驟(7);否則進入下一步;
(6)用戶釋放chunk,判斷new bin的分配次數(shù)是否大于分配閾值,是則釋放new bin所占內存空間,結束;否則不釋放new bin所在內存空間,結束;
(7)用戶釋放chunk,chunk進入延遲分配鏈表,結束。
進一步地,所述步驟(4)具體包括以下子步驟:
(41)根據(jù)chunk的大小在small bin和large bin中找到相應大小的bin,若在small bin中找到合適bin,則進入步驟(42);否則在large bin中找到合適的bin后分配結束;
(42)判斷該bin的分配次數(shù)是否小于分配閾值k;若是則進入步驟(45);否則進入下一步;
(43)判斷該chunk是否已有申請的new bin,是則回到步驟(42);否則進入下一步;
(44)申請一個新的new bin,若申請成功則new bin的大小Nnb=k×Nc,其中Nc為新分配chunk的大小,之后回到步驟(42);否則報錯系統(tǒng)內存不足,結束分配;
(45)從該bin鏈表中選取一個chunk返回給用戶,同時該bin的分配次數(shù)累加1,分配結束。
進一步地,所述步驟(7)具體包括以下子步驟:
(71)大小為δn的chunk被釋放后進入延遲分配鏈表,延遲分配鏈表為其標記一個窗口,窗口初始大小為φ;
(72)更新延遲分配鏈表中其他chunk標記窗口的大小Ni=Ni-δn,i=1,2,3,...,n-1,其中i表示chunk進入延遲分配鏈表的順序;
(73)判斷N1<0是否成立,是則將延遲分配鏈表鏈表中最先進入的chunk取出放回到其他空閑內存分配鏈表中以待下一次分配,同時更新所有chunk進入鏈表的順序i=i-1,結束;否則直接結束。
進一步地,分配閾值k的取值范圍為100<k<50000,優(yōu)選k=4096;延遲分配鏈表的標記窗口初始大小為φ,φ的取值范圍為1KB<φ<4096KB,優(yōu)選φ=4KB,
總體而言,通過本發(fā)明所構思的以上技術方案與現(xiàn)有技術相比,采用本發(fā)明技術方案可以有效的降低NVRAM內存的使用損耗,提高NVRAM內存使用壽命。
附圖說明
圖1為glibc malloc內存分配器中內存分配鏈表示意圖;
圖2為本發(fā)明內存分配鏈表示意圖;
圖3為本發(fā)明方法總流程圖;
圖4為本發(fā)明方法在Bins中根據(jù)chunk大小尋找合適bin的方法流程圖;
圖5為本發(fā)明方法在chunk進入延遲分配鏈表的方法流程圖。
具體實施方式
為了使本發(fā)明的目的、技術方案及優(yōu)點更加清楚明白,以下結合附圖及實施例,對本發(fā)明進行進一步詳細說明。應當理解,此處所描述的具體實施例僅僅用以解釋本發(fā)明,并不用于限定本發(fā)明。此外,下面所描述的本發(fā)明各個實施方式中所涉及到的技術特征只要彼此之間未構成沖突就可以相互組合。
如圖2所示為本發(fā)明內存分配鏈實施例示意圖,其中包括:
Fastbins,一個數(shù)組,用于記錄所有fast bin鏈表,鏈表使用FIFO法進行鏈表中chunk的插入或刪除;
Bins,一個數(shù)組,用于記錄所有new bin、small bin和large bin鏈表,new bin和small bin鏈表采用FIFO法進行鏈表中chunk的插入或刪除,每個new bin和small bin鏈表都設置一個計數(shù)器,記錄各自的分配次數(shù),考慮到現(xiàn)在以PCM為代表的NVRAM壽命普遍為107到108次寫入,廣泛使用的64位機器下int數(shù)據(jù)類型為32比特,232=4294967296,達到了109數(shù)量級,所以int數(shù)據(jù)類型完全夠用。那么本方案額外引入的空間開銷僅為:63×32bit=252B,是非常小的。
現(xiàn)在預先設定分配閾值k=4096,即當某個bin鏈表內大小為104B的chunks被分配了4096次之后,表明用戶正在頻繁申請大小為104B的chunks。那么為了避免對剛釋放塊的重用,此時就不再從空閑分配鏈表中獲取大小為104B的chunk了,而是直接以4KB為單位向操作系統(tǒng)通過mmap()系統(tǒng)調用申請一塊新的大小為104*4096/1024=416KB的內存區(qū)域,暫且命名為new bin1。然后將new bin1按chunk的大小進行劃分,并將new bin1的分配閾值k也設置為4096,正好是劃分后的可以供每個chunk分配一次。后續(xù)所有對大小為n的chunk的分配請求都將被new bin1處理而不是由空閑分配鏈表處理。一段時間后如果new bin1的分配次數(shù)也達到了分配閾值k,那么同樣,先以4KB為單位向操作系統(tǒng)通過mmap()系統(tǒng)調用申請一塊新的大小為416KB的內存區(qū)域,命名為new bin2,同樣將new bin2按chunk的大小進行劃分,并將new bin2的分配閾值k也設置為4096。以此類推。
值得注意的是,如果new bin1中的chunk被釋放,將被還回new bin1而不是空閑分配鏈表中。另外,申請new bin2后new bin1所占用的內存區(qū)域才有可能被釋放。如此確保了向操作系統(tǒng)申請的mmap()區(qū)域也不是剛釋放回去的。
延遲分配鏈表,用于保存剛被用戶釋放的fast chunk、small chunk和large chunk,鏈表使用FIFO法進行鏈表中chunk的插入或刪除,每個新進入的chunk會被標記一個窗口,現(xiàn)在假設預先定好的窗口大小φ=4KB,最近釋放的3個chunk的大小分別為δ=64B、δ1=24B和δ2=1024B。當?shù)谝粋€chunk被釋放時,它將首先進入延遲分配鏈表并將其窗口大小window_alloc初始化為φ=4KB;當?shù)诙€大小為δ1的chunk被釋放進入該鏈表時,就將第一個chunk的窗口大小改為φ-δ1,同時將第二個大小為δ1的chunk的窗口大小也初始化為φ=4KB;當?shù)谌齻€大小為δ2的chunk進入鏈表時,將第一個chunk的窗口改為φ-δ1-δ2,第二個chunk的窗口改為φ-δ2,第三個大小為δ2的chunk的窗口大小初始化為φ=4KB。
在每次插入新的chunk之后,都進行對鏈表頭的檢查工作。如果鏈表頭部的chunk的窗口大小在減去剛進入鏈表的chunk大小之后小于零,則將之從鏈表頭部取出并放回到管理chunks的空閑分配鏈表中去以待下一次被分配。這樣可以保證同一個chunk在分配φ大小的空間前不會再被使用到,有效避免了對剛釋放塊的重用。
值得注意的是,可以看出延遲分配鏈表總是會占用φ大小的空間,φ可以由系統(tǒng)管理人員設定以適應不同的負載均衡需求。當負載的磨損極其不均勻時(比如惡意攻擊),φ可以適當設定地大一些,有助于實現(xiàn)更大地址空間的磨損均衡;當負載是相對典型的應用時,φ可以適當設定地小一些,減少系統(tǒng)調用的次數(shù)有助于提升應用分配的性能。
如圖3所示本發(fā)明內存分配方法包括以下步驟:
(1)將用戶請求內存空間的大小轉換為實際需要分配的chunk空間大小;
(2)判斷chunk空間大小是否小于64B,若是則進行步驟(3);否則進行步驟(4);
(3)在Fastbins中找到一個合適的chunk;分配完成,進入步驟(7);
(4)在Bins中找到一個合適的chunk;分配完成;
(5)判斷chunk是否在small bin或large bin中,若是則進入步驟(7);否則進入下一步;
(6)用戶釋放chunk,判斷new bin的分配次數(shù)是否大于分配閾值,是則釋放new bin所占內存空間,結束;否則不釋放new bin所在內存空間,結束;
(7)用戶釋放chunk,chunk進入延遲分配鏈表,結束。
如圖4所示本發(fā)明步驟中步驟(4)包括以下子步驟:
(41)根據(jù)chunk的大小在small bin和large bin中找到相應大小的bin,若在small bin中找到合適bin,則進入步驟(42);否則在large bin中找到合適的bin后分配結束;
(42)判斷該bin的分配次數(shù)是否小于分配閾值k;若是則進入步驟(45);否則進入下一步;
(43)判斷該chunk是否已有申請的new bin,是則回到步驟(42);否則進入下一步;
(44)申請一個新的new bin,若申請成功則new bin的大小Nnb=k×Nc,其中Nc為新分配chunk的大小,之后回到步驟(42);否則報錯系統(tǒng)內存不足,結束分配;
(45)從該bin鏈表中選取一個chunk返回給用戶,同時該bin的分配次數(shù)累加1,分配結束。
如圖5所示本發(fā)明步驟中步驟(7)包括以下子步驟:
(71)大小為δn的chunk被釋放后進入延遲分配鏈表,延遲分配鏈表為其標記一個窗口,窗口初始大小為φ;
(72)更新延遲分配鏈表中其他chunk標記窗口的大小Ni=Ni-δn,i=1,2,3,...,n-1,其中i表示chunk進入延遲分配鏈表的順序;
(73)判斷N1<0是否成立,是則將延遲分配鏈表鏈表中最先進入的chunk取出放回到其他空閑內存分配鏈表中以待下一次分配,同時更新所有chunk進入鏈表的順序i=i-1,結束;否則直接結束。
進一步地,分配閾值k的取值范圍為100<k<50000,優(yōu)選k=4096;延遲分配鏈表的標記窗口初始大小為φ,φ的取值范圍為1KB<φ<4096KB,優(yōu)選φ=4KB,
以上所述僅為本發(fā)明的較佳實施例而已,并不用以限制本發(fā)明,凡在本發(fā)明的精神和原則之內所作的任何修改、等同替換和改進等,均應包含在本發(fā)明的保護范圍之內。