【作業系統筆記】動態儲存管理

蘭亭風雨發表於2014-03-08

轉載請註明出處:http://blog.csdn.net/ns_code/article/details/20661785


    作業系統中常用來管理記憶體的動態分配和回收的方法有邊界標識法和夥伴系統。

邊界標識法

    系統將所有的空閒塊連結在一個雙重迴圈連結串列結構的可利用空間表中。系統的特點在於:在每個記憶體區的頭部和底部兩個邊界上分別設有標識,以標識該區域是佔用塊或空閒塊,使得在回收使用者釋放的空閒塊時易於判別在物理位置上與其相鄰的記憶體區域是否為空閒塊,以便將所有地址連續的空閒塊組合成一個更大的可利用的空閒塊。

    可利用空間表的結構如下圖所示:

    

其中space為一組連續的儲存單元,是可以分配給使用者使用的記憶體區域,它的大小由頭部的size屬性指示,頭部的llink域和rlink域分別指向上一個可用空間表和下一個可用空間表,底部的uplink域指向本節點頭部,頭部和底部都有個tag域,用來表示該當前塊是空閒塊還是佔用塊。

    記憶體分配

採用該方法時,記憶體分配很簡單,採用首次擬合分配、最佳擬合分配、最差擬合分配均可。另外,為了避免修改指標,約定將該節點中的高地址部分分配給使用者。很明顯,如果每次分配都從同一個節點開始查詢的話,勢必會造成儲存量小的節點密集在頭指標所指節點附近,這同樣會增加查詢較大空閒塊的時間,因此在每次分配後,令指標指向剛剛分配過的節點的後續節點,這樣下一次記憶體分配時就從不同的節點進行查詢,避免了上述問題。

    記憶體回收

某佔用塊被釋放後,檢查其左右鄰記憶體塊是否為空閒塊,如果是則連線起來成為一個更大的可用記憶體塊,並修改相應的域。

 

夥伴系統

在夥伴系統中,無論是佔用塊還是空閒塊,其大小均為2的整數次冪。比如,如果使用者請求申請n個位元組的記憶體區,那麼系統分配給它的佔用塊大小為2^k(2^(k-1) < n = < 2^k)。

可利用的空間表的結構如下圖所示:


其中,kva域的值為2的冪次k,space是一個大小為2^k個字的連續記憶體空間。

為了再分配時方便查詢,系統將所有大小相同的空閒塊用連結串列連線在一起,最後再索引到不同kval對應的位置,這有點類似於雜湊表的結構。如下圖所示:

 

    記憶體分配

假設初始可用表中只有2^k大小的空閒塊,我們要申請n(2^(k-2) < n = < 2^(k-1))個位元組,的記憶體空間,此時由於節點為2^(k-1)大小的子表為空,則需從節點為2^k的子表中取出一塊,將其中的一半分配給使用者,剩餘的一半作為一個新節點插入到節點大小為2^(k-1)的字表中。同樣,若2^(k-i-1) < n =< 2^(k-i),並且所有節點大小小於2^k的子表均為空,則同樣需從節點大小為2^k的子表中取出一塊,將其中的2^(k-i)的一小部分分配給使用者,剩餘部分分成若干個節點分別插入到節點大小為2^(k-i)、2^(k-i+1)。。。2^(k-1)的子表中。

下圖展示了記憶體分配的情況:

 

 

    記憶體回收

在夥伴系統中,僅會考慮將互為夥伴的兩個空閒塊合併在一起。我們在分配時經常需要將一個大的空閒塊分裂成兩個大小相等的儲存區,這兩個由同一個大塊分裂出來的小塊就互為夥伴塊。若有兩個空閒塊,即時大小相同且地址相鄰,但如果不是由同一個大塊分裂出來的,也不會合並在一起。

起始地址為p,大小為2^k的記憶體塊,其夥伴塊的起始地址滿足如下關係:

若p%2^(k+1)=0,則

夥伴塊的起始地址 = p+2^k;

若p%2^(k+1)=2^k,則

夥伴塊的起始地址 = p-2^k;

回收情況如下圖所示:





相關文章