內(nèi)存管理系統(tǒng)和方法
【技術(shù)領(lǐng)域】
[0001]本公開的實(shí)施例涉及內(nèi)存管理系統(tǒng)和方法,尤其涉及內(nèi)存的分配和釋放。
【背景技術(shù)】
[0002]在C/C++程序的運(yùn)行過程中,經(jīng)常需要?jiǎng)討B(tài)地分配、釋放不同大小的內(nèi)存塊,最常見的就是使用new/delete操作符來為各種類型的對(duì)象分配和釋放內(nèi)存。大多數(shù)編譯器對(duì)這兩個(gè)操作符的缺省實(shí)現(xiàn)是調(diào)用C運(yùn)行時(shí)庫的malloc和free,但由于分配的內(nèi)存塊大小不定、釋放順序不定,頻繁使用時(shí)容易產(chǎn)生內(nèi)存碎片;另外,調(diào)用這兩個(gè)函數(shù)也比較耗時(shí),C運(yùn)行時(shí)庫實(shí)際還會(huì)多分配一些字節(jié)來維護(hù)一些信息,如內(nèi)存塊的大小等。用戶請求分配的字節(jié)越少,額外的內(nèi)存開銷越明顯,這些情況對(duì)應(yīng)用程序的性能和穩(wěn)定性不利。
【發(fā)明內(nèi)容】
[0003]本發(fā)明目的是解決上述問題中的一個(gè)或多個(gè)。
[0004]本發(fā)明在一個(gè)方面提供一種內(nèi)存管理方法,包括:
[0005]建立大內(nèi)存塊;
[0006]在所述大內(nèi)存塊中建立小內(nèi)存塊;
[0007]接收請求分配預(yù)定大小內(nèi)存的內(nèi)存分配請求;
[0008]將所述預(yù)定大小與閾值進(jìn)行比較;
[0009]如果所述預(yù)定大小不大于所述閾值,判斷所述大內(nèi)存塊中是否存在空閑小內(nèi)存塊;
[0010]如果所述大內(nèi)存塊中存在空閑小內(nèi)存塊,為所述請求分配所述空閑小內(nèi)存塊。
[0011]本發(fā)明在另一個(gè)方面提供一種內(nèi)存管理方法,包括:
[0012]接收內(nèi)存釋放請求,所述請求包括要釋放的內(nèi)存塊的地址和大?。?br>[0013]將所述內(nèi)存塊大小與閾值進(jìn)行比較;
[0014]如果所述內(nèi)存塊大小不大于所述閾值;
[0015]根據(jù)所述內(nèi)存塊大小計(jì)算節(jié)點(diǎn)分配器索引值;
[0016]由與所述索引值對(duì)應(yīng)的節(jié)點(diǎn)分配器根據(jù)所述地址釋放所述內(nèi)存塊。
[0017]本發(fā)明在又一個(gè)方面提供一種內(nèi)存管理系統(tǒng),包括:
[0018]用于管理大內(nèi)存塊的塊分配器;
[0019]用于管理小內(nèi)存塊的節(jié)點(diǎn)分配器;和
[0020]用于管理節(jié)點(diǎn)分配器的節(jié)點(diǎn)分配管理器。
[0021]根據(jù)本發(fā)明,預(yù)先通過malloc分配較大的內(nèi)存塊,當(dāng)應(yīng)用程序需要小內(nèi)存塊時(shí),從大內(nèi)存塊中分配;應(yīng)用程序釋放小內(nèi)存塊時(shí),將其歸還到大內(nèi)存塊中。大內(nèi)存塊往往過較長時(shí)間后才通過free釋放,甚至在程序退出前才釋放。因此,可以減少malloc/free的調(diào)用,使內(nèi)存的分配釋放更高效。
[0022]本發(fā)明提供的小內(nèi)存塊的分配方案,其特點(diǎn)是分配、釋放操作非??欤苡行У販p少內(nèi)存碎片,保證較高的內(nèi)存利用率。此方案適用于需長時(shí)間運(yùn)行、頻繁分配釋放小內(nèi)存塊的場合。尤其是考慮到絕大多數(shù)程序在運(yùn)行過程中頻繁分配、釋放的通常是不同尺寸的小內(nèi)存塊,本發(fā)明尤其有用。
【附圖說明】
[0023]從下面結(jié)合附圖對(duì)本發(fā)明的【具體實(shí)施方式】的描述中可以更好地理解本發(fā)明,其中:
[0024]圖1 出根據(jù)本發(fā)明例性實(shí)施例的內(nèi)存管理系統(tǒng);
[0025]圖2 出根據(jù)本發(fā)明一個(gè)例性實(shí)施例的鏈表;
[0026]圖3 出根據(jù)本發(fā)明另一個(gè)例性實(shí)施例的鏈表;
[0027]圖4 出根據(jù)本發(fā)明又一個(gè)例性實(shí)施例的鏈表;
[0028]圖5示出根據(jù)本發(fā)明示例性實(shí)施例的大內(nèi)存塊的鏈表和小內(nèi)存塊的鏈表形成的嵌套結(jié)構(gòu);
[0029]圖6示出根據(jù)本發(fā)明的示例性實(shí)施例的內(nèi)存分配方法;
[0030]圖7示出根據(jù)本發(fā)明的示例性實(shí)施例的內(nèi)存釋放方法;
[0031]圖8示出根據(jù)本發(fā)明的示例性實(shí)施例的計(jì)算裝置。
【具體實(shí)施方式】
[0032]下面將詳細(xì)描述本發(fā)明各個(gè)方面的特征和示例性實(shí)施例。下面的描述涵蓋了許多具體細(xì)節(jié),以便提供對(duì)本發(fā)明的全面理解。但是,對(duì)于本領(lǐng)域技術(shù)人員來說顯而易見的是,本發(fā)明可以在不需要這些具體細(xì)節(jié)中的一些細(xì)節(jié)的情況下實(shí)施。下面對(duì)實(shí)施例的描述僅僅是為了通過示出本發(fā)明的示例來提供對(duì)本發(fā)明更清楚的理解。本發(fā)明絕不限于下面所提出的任何具體配置,而是在不脫離本發(fā)明的精神的前提下覆蓋了相關(guān)元素或部件的任何修改、替換和改進(jìn)。
[0033]本發(fā)明中的術(shù)語“大內(nèi)存塊”和“小內(nèi)存塊”中的相對(duì)術(shù)語“大”和“小”是相對(duì)而言的。即“大內(nèi)存塊”是指相對(duì)于“小內(nèi)存塊”字節(jié)數(shù)多的內(nèi)存塊,“小內(nèi)存塊”是指相對(duì)于“大內(nèi)存塊”字節(jié)數(shù)小的內(nèi)存塊。通常“大內(nèi)存塊”中可以建立一個(gè)或多個(gè)小內(nèi)存塊。
[0034]圖1示出根據(jù)本發(fā)明示例性實(shí)施例的內(nèi)存管理系統(tǒng)。內(nèi)存管理系統(tǒng)包括用于管理大內(nèi)存塊的塊分配器101,用于管理小內(nèi)存塊的節(jié)點(diǎn)分配器102,用于管理節(jié)點(diǎn)分配器的節(jié)點(diǎn)分配管理器103。
[0035]塊分配器(ChunkAllocator) 101對(duì)大內(nèi)存塊的管理主要包括分配和釋放大內(nèi)存塊。在本發(fā)明的一個(gè)例實(shí)施例中,塊分配器101以鏈表(例如,單鏈表)的方式管理大內(nèi)存塊。鏈表的每個(gè)節(jié)點(diǎn)是一個(gè)大內(nèi)存塊。
[0036]圖2給出了塊分配器101可以使用的鏈表的例子。在圖2的示例中,鏈表包括節(jié)點(diǎn)N1-N4。雖然圖2中示出四個(gè)節(jié)點(diǎn),本領(lǐng)域的技術(shù)人員可以理解,鏈表可以包括更多或更少的節(jié)點(diǎn)。
[0037]每個(gè)節(jié)點(diǎn)都有一個(gè)頭部(也稱作指針域)H。頭部可以用于存放下一個(gè)節(jié)點(diǎn)的地址。例如,節(jié)點(diǎn)N1的頭部Η存放節(jié)點(diǎn)Ν2的地址,節(jié)點(diǎn)Ν2的頭部存放節(jié)點(diǎn)Ν3的地址。節(jié)點(diǎn)Ν3的頭部存放節(jié)點(diǎn)Ν4的地址。節(jié)點(diǎn)Ν4頭部存儲(chǔ)值“NULL”,表示這是最后一個(gè)節(jié)點(diǎn)。
[0038]每個(gè)節(jié)點(diǎn)還包括用于存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)域D,即可用的內(nèi)存空間。根據(jù)本發(fā)明的示例實(shí)施例,鏈表還可以包括頭指針HP,保存有鏈表中第一節(jié)點(diǎn)N1的地址。鏈表可由頭指針HP來唯一確定,在C語言中例如可用“結(jié)構(gòu)指針”來描述頭指針。由于頭指針HP中存放的是鏈表的第一個(gè)節(jié)點(diǎn)的地址,因此如果頭指針的值為NULL,表示鏈表含有0個(gè)節(jié)點(diǎn)。
[0039]要釋放一個(gè)大內(nèi)存塊,即刪除一個(gè)節(jié)點(diǎn)時(shí),塊分配器101會(huì)調(diào)用庫函數(shù),例如調(diào)用庫函數(shù)free,從而釋放相應(yīng)的空間。塊分配器101還會(huì)修改前一節(jié)點(diǎn)中存儲(chǔ)的地址,將其修改為刪除節(jié)點(diǎn)的下一節(jié)點(diǎn)的地址。以圖2給出的鏈表為例,例如,當(dāng)刪除節(jié)點(diǎn)N3時(shí),塊分配器101會(huì)調(diào)用庫函數(shù)free,釋放該大內(nèi)存塊,塊分配器101還會(huì)將節(jié)點(diǎn)N2頭部改為存儲(chǔ)N4的地址。如果要?jiǎng)h除的是第一節(jié)點(diǎn)N1,塊分配器101會(huì)調(diào)用庫函數(shù)free,釋放節(jié)點(diǎn)N1,塊分配器101還會(huì)從節(jié)點(diǎn)N1頭部獲取N2的地址,從而將頭指針的地址改為N2的地址。
[0040]如果塊分配器101要遍歷大內(nèi)存塊鏈表,依次釋放掉所有的大內(nèi)存塊,這時(shí)會(huì)從第一節(jié)點(diǎn)開始。還是以圖2給出的鏈表為例,塊分配器101會(huì)先釋放第一節(jié)點(diǎn)N1,并將頭指針的地址改為第二節(jié)點(diǎn)N2的地址(事實(shí)上,這時(shí)第二節(jié)點(diǎn)成為新的第一節(jié)點(diǎn))。然后塊分配器101會(huì)釋放第二節(jié)