今天學習到 linux 記憶體分配問題,有些不明白,什麼是記憶體碎片問題?以及為什麼maloc()等函式每次分配記憶體後都會用 free()釋放資源,為什麼還會產生碎片問題?記憶體碎片問題如何產生 及 如何解決呢?
以下是自己今天學習心得:
記憶體碎片概念:
記憶體碎片問題分為內部碎片和外部碎片兩種。
1.內部碎片是由於採用固定大小的記憶體分割槽,當乙個程序不能完全使用分給它的固定記憶體區域時,就將該程序分配後剩餘的部分稱為內碎片。通常內碎片難以避免;
2.外部碎片是由於某些未分配的連續區域太小,不足以為任意程序分配記憶體資源的記憶體塊大小,此時稱這些不可用的記憶體塊大小為外部碎片
對於malloc()等函式,每次申請完記憶體後都會釋放,但每次釋放的記憶體大小及釋放時間的不同就會產生記憶體碎片。比如:在記憶體單元100的起始位址到記憶體單元200之間,共申請了100個1位元組的空間。在free()時,釋放了記憶體位址為奇數的記憶體單元(如101,103,105……)而偶數單元不釋放,釋放了50個1位元組空間,雖然總空間數為50位元組,但由於這50個1位元組空間不連續。當下次要申請2位元組的記憶體單元時,卻無法在100到200的記憶體位址單元中申請到空間,於是就產生記憶體碎片問題。
為什麼會產生記憶體碎片?
分頁機制:相比較固定分配分割槽,內碎片問題已經明顯減少
分段機制:消除內碎片問題,但會產生外碎片問題
夥伴演算法可以解決外碎片問題,其演算法思想如下:
無論已經分配的分割槽還是空閒分割槽,其大小均為2的k次冪,k為整數,1<=k<=m,其中2^1表示分配的最小分割槽大小,2^m 表示分配的最大分割槽的大小。在系統開始執行時,整個記憶體區是乙個大小為2^m的空閒分割槽,隨著系統執行,空閒區的不斷劃分會形成若干不連續的空閒分割槽,將這些空閒分割槽按照分割槽的大小進行分類,對於每一類具有相同大小的所有空閒分割槽,單獨成立乙個空閒分割槽雙向鍊錶。這樣,不同大小的空閒分割槽就形成了k(0<=k<=m)個空閒分割槽鍊錶。
當需要為程序分配乙個長度為n 的儲存空間時,首先計算i 的值,使2^(i-1)< n < 2^ i ,然後在空閒分割槽大小為i 的空閒區煉表中查詢。若找到,則把該空閒分割槽分配給該程序。否則,表明長度為2^ i 的空閒分割槽已經耗盡,則在長度為2^(i+1)的空閒分割槽鍊錶中查詢。若存在大小為2^(i+1)的空閒分割槽,則將該分割槽分為連個大小均為2^ i 的塊,乙個塊分配給該程序,乙個塊掛載在長度大小為2^ i 的空閒分割槽鍊錶中。若大小為2^(i+1)的空閒分割槽也已經耗盡,則尋找大小為2^(i+2)的空閒分割槽,若找到,則對該分割槽進行兩次劃分,第一次劃分,將大小為2^(i+2)的分割槽分為兩個大小為2^(i+1)的空閒分割槽,乙個掛載在大小為2^(i+1)的空閒分割槽上,乙個再次分割為兩個大小為2^ i 的分割槽,乙個掛載在大小為2^ i 的空閒分割槽上,乙個用於分配給該程序;如果未找到大小為2^ ( i+2 ) 的空閒分割槽,則在2^( i+3) 的空閒分割槽上尋找,一次重複以上步驟,指導找到空閒區
在linux中將這記憶體分為10個空閒分割槽鍊錶,0-9,大小範圍是:2^0 - 2^9
也正是基於以上兩個條件才稱該演算法為夥伴演算法
linux夥伴演算法中涉及到的資料結構:
free_area_t free_area[max_order];
我們再次對free_area_t 給予較詳細的描述。
其中list_head
域是乙個通用的雙向鍊錶結構,鍊錶中元素的型別將為
mem_map_t(
即struct page結構)
。map
域指向乙個位圖,其大小取決於現有的頁面數。
free_area第k
項位圖的每一位,描述的就是大小為2k個
頁面的兩個夥伴塊的狀態。如果點陣圖的某位為
0,表示一對兄弟塊中或者兩個都空閒,或者兩個都被分配,如果為
1,肯定有一塊已被分配。當兄弟塊都空閒時,核心把它們當作乙個大小為
2k+1
的單獨快來處理
Linux夥伴系統演算法 防止記憶體碎片的產生
夥伴系統也存在一些問題,在系統長時間執行後,物理記憶體會出現很多碎片,如圖所示 這是雖然可用記憶體頁還有很多,但是最大的連續物理記憶體也只有一頁,這對於使用者程式不成問題,因為使用者程式通過頁表對映,應用程式看到的總是連續的虛擬記憶體。但是對於核心來說就不行了,因為核心有時候需要使用連續的物理記憶體...
記憶體管理之夥伴演算法
通常情況下,乙個高階作業系統必須要給程序提供基本的 能夠在任意時刻申請和釋放任意大小記憶體的功能,就像malloc 函式那樣,然而,實現malloc 函式並不簡單,由於程序申請記憶體的大小是任意的,如果作業系統對malloc 函式的實現方法不對,將直接導致乙個不可避免的問題,那就是記憶體碎片。記憶體...
記憶體管理演算法 Buddy夥伴演算法
buddy演算法的優缺點 1 儘管夥伴記憶體演算法在記憶體碎片問題上已經做的相當出色,但是該演算法中,乙個很小的塊往往會阻礙乙個大塊的合併,乙個系統中,對記憶體塊的分配,大小是隨機的,一片記憶體中僅乙個小的記憶體塊沒有釋放,旁邊兩個大的就不能合併。2 演算法中有一定的浪費現象,夥伴演算法是按2的冪次...