內存碎片及夥伴算法

今天學習到 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


以上過程的逆過程就是夥伴算法的釋放過程,釋放過程需要滿足兩個條件:1.兩個塊具有相同的大小  2.它們的物理地址是連續的

也正是基於以上兩個條件才稱該算法爲夥伴算法



Linux夥伴算法中涉及到的數據結構:

free_area_t    free_area[MAX_ORDER];

我們再次對free_area_t  給予較詳細的描述。

#difine   MAX_ORDER  10

type struct free_area_struct {

           struct list_head   free_list

                 unsigned  int    *map

 } free_area_t


 其中list_head域是一個通用的雙向鏈表結構,鏈表中元素的類型將爲mem_map_t(struct page結構)Map域指向一個位圖,其大小取決於現有的頁面數。free_areak項位圖的每一位,描述的就是大小爲2k頁面的兩個夥伴塊的狀態。如果位圖的某位爲0,表示一對兄弟塊中或者兩個都空閒,或者兩個都被分配,如果爲1,肯定有一塊已被分配。當兄弟塊都空閒時,內核把它們當作一個大小爲2k+1的單獨快來處理


轉自:https://blog.csdn.net/man_lady_horse/article/details/47169137

發佈了55 篇原創文章 · 獲贊 86 · 訪問量 97萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章