linux虛擬內存子系統簡介

這裏寫圖片描述

MMU(內存管理單元)

負責將虛擬地址轉換爲物理地址,數據存放在主存上,cpu訪存時至少需要兩次,第一次獲取物理地址;第二次才獲取數據。

    TLB:爲了改善虛擬地址到物理地址的轉換速度,提高cpu訪存速度。

       原理:TLB利用的是頁表的訪問局部性,即當一個轉換的虛擬頁號被使用時,它可能在不久

         的將來再次被使用到。TLB是一種高速緩存,當cpu訪問第一次某個線性地址時,通

         過計算獲得對應的物理地址,同時,該線性地址和物理地址的對應關係保存在一個

         TLB表項中,以後對同一線性地址的訪問,直接從TLB表項中獲取物理地址即可。

      TLB內部存放的基本是頁表條目,對應着RAM中存放的頁表條目。頁表條目的大小固定不變

      的,所以TLB容量越大,所能存放的頁表條目越多,TLB 的命中率也越大。這是內存優化可

      以考慮的一個點



buddy allocator(夥伴系統):是一種動態內存分配方式,內存中有多個分區,規定每個分區都是2^n(n可不同),爲相同大小的空閒分區設立一個空閒分區雙向鏈表,即每個鏈表中空閒分區n都相同。分配時,首先計算n值,根據n值在對應大小爲2^n的空閒分區鏈表中查找,如果找到即分配,找不到則將其向上擴在2^(n+1)鏈表中查找,把一個大小爲2^(n+1)d的空閒分區分成兩個相等的部分,這兩個大小相等的分區就稱爲夥伴,其中一個用於分配,另一個加入2^i的空閒分區鏈表。回收時,如果夥伴是空閒的,則會合併成更大的空閒分區,加入到更大的鏈表中。


slab allocator

    一些需要頻繁使用的同樣大小數據經常在使用後不久又再次被用到,而這些內核對這些數據內存的分配和初始化的時間可能遠遠超過使用和釋放內存的時間,所以首先從操作系統申請一大塊內存,並將其分割成各種尺寸的塊Chunk,並把尺寸相同的塊分成組Slab Class。將內存對象使用過後使用slab保存起來,以備將來再次使用。

圖 1 給出了 slab 結構的高層組織結構。在最高層是 cache_chain,這是一個 slab 緩存的鏈接列表。這對於 best-fit 算法非常有用,可以用來查找最適合所需要的分配大小的緩存(遍歷列表)。cache_chain 的每個元素都是一個 kmem_cache 結構的引用(稱爲一個 cache)。它定義了一個要管理的給定大小的對象池。

圖 1. slab 分配器的主要結構

圖 1. slab 分配器的主要結構

每個緩存都包含了一個 slabs 列表,這是一段連續的內存塊(通常都是頁面)。存在 3 種 slab:

  • slabs_full

  • 完全分配的 slab

  • slabs_partial

  • 部分分配的 slab

  • slabs_empty

  • 空 slab,或者沒有對象被分配

注意 slabs_empty 列表中的 slab 是進行回收(reaping)的主要備選對象。正是通過此過程,slab 所使用的內存被返回給操作系統供其他用戶使用。

slab 列表中的每個 slab 都是一個連續的內存塊(一個或多個連續頁),它們被劃分成一個個對象。這些對象是從特定緩存中進行分配和釋放的基本元素。注意 slab 是 slab 分配器進行操作的最小分配單位,因此如果需要對 slab 進行擴展,這也就是所擴展的最小值。通常來說,每個 slab 被分配爲多個對象。

由於對象是從 slab 中進行分配和釋放的,因此單個 slab 可以在 slab 列表之間進行移動。例如,當一個 slab 中的所有對象都被使用完時,就從slabs_partial 列表中移動到 slabs_full 列表中。當一個 slab 完全被分配並且有對象被釋放後,就從 slabs_full 列表中移動到slabs_partial 列表中。當所有對象都被釋放之後,就從 slabs_partial 列表移動到 slabs_empty 列表中。


髒頁

因爲硬盤的讀寫速度遠趕不上內存的速度,系統就把讀寫比較頻繁的數據事先放到內存中,以提高讀寫速度,這就叫高速緩存,linux是以頁作爲高速緩存的單位,當進程修改了高速緩存裏的數據時,該頁就被內核標記爲髒頁,內核將會在合適的時間把髒頁的數據寫到磁盤中去,以保持高速緩存中的數據和磁盤中的數據是一致的。


bdflush

用來定期將內存中的髒頁緩存寫到磁盤上的進程


kswapd

處理頁面交換的一種守護進程,在內存不足時,將一些進程的頁面交換到swap空間之中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章