Linux 內核原理之內存系統

buddy system

進程向內核申請內存需要地址連續的內存塊,linux如何處理來儘可能保持內存塊的連續的呢?答案buddy system。來看下buddy system內存地址分配策略。

首先假設系統一開始有共16個字節的內存,然後被分出去8 byte。狀態圖如下:

在這裏插入圖片描述
可以看到左邊數組中存放的都是等大的塊,內存不連續的等大塊以鏈表的方式存放在相應的索引處。

如果這個時候,有個2字節的請求,剩餘的6個字節就會被分別放在 2 1 2^1 2 2 2^2 處。

當內存回收時,內核會在等大塊中,發現可以合併的內存塊,並放到更上層。比如上面的8個字節內存被釋放時,兩個8字節的內存塊會被發現是連續的,合併放到 2 4 2^4 位置。

buddy system存在內存碎片問題?

當內存被頻繁的申請和釋放,buddy system就會有內存碎片問題。進程要申請一塊內存,剩餘內存總量是夠的,但是內存地址不連續。

下面簡單舉個內存碎片的例子:

初始狀態:

{ [0-15] }

分配2 byte:
{ [0-7] } , { [8-11] } , { [12-13] }

申請5 byte
{ [8-11] } , {[12,13],[6-7]}(內存碎片), { [5-5] }

虛擬地址空間

4GB虛擬地址空間被分成用戶空間和內核空間兩部分。

用戶空間

代碼段,數據段和BSS段是連續存放的。代碼段放機器碼,數據段放已初始化的靜態變量或全局變量。BSS段包含未初始化全局變量。(可以使用size查看編譯程序的內存區域如size /bin/ls

物理地址空間

物理地址空間到虛擬地址空間的映射

物理地址空間的結構

區域 地址區間
ZONE_DMA 16M
ZONE_NORMAL 896M
ZONE_HIGHMEM 896M+