1. 程式人生 > 其它 >記憶體監控分析

記憶體監控分析

虛擬記憶體

  • 我們通常所說的記憶體容量,比如 8GB,其實指的是實體記憶體。實體記憶體也稱為主存,大多數計算機用的主存都是動態隨機訪問記憶體(DRAM)。只有核心才可以直接訪問實體記憶體。
  • Linux 核心給每個程序都提供了一個獨立的虛擬地址空間,並且這個地址空間是連續的。這樣,程序就可以很方便地訪問記憶體,更確切地說是訪問虛擬記憶體。
  • 虛擬地址空間的內部又被分為核心空間和使用者空間兩部分,程序在使用者態時,只能訪問使用者空間記憶體;只有進入核心態後,才可以訪問核心空間記憶體。
  • 並不是所有的虛擬記憶體都會分配實體記憶體,只有那些實際使用的虛擬記憶體才分配實體記憶體,並且分配後的實體記憶體,是通過記憶體對映來管理的。

記憶體對映

  • 記憶體對映,其實就是將虛擬記憶體地址對映到實體記憶體地址。為了完成記憶體對映,核心為每個程序都維護了一張頁表,記錄虛擬地址與實體地址的對映關係,如下圖所示:
  • 頁表實際上儲存在 CPU 的記憶體管理單元 MMU 中,這樣,正常情況下,處理器就可以直接通過硬體,找出要訪問的記憶體。
  • 當程序訪問的虛擬地址在頁表中查不到時,系統會產生一個缺頁異常,進入核心空間分配實體記憶體、更新程序頁表,最後再返回使用者空間,恢復程序的執行。
  • 頁的大小隻有 4 KB ,導致的另一個問題就是,整個頁表會變得非常大。比方說,僅 32 位系統就需要 100 多萬個頁表項(4GB/4KB),才可以實現整個地址空間的對映。
  • 為了解決頁表項過多的問題,Linux 提供了兩種機制,也就是多級頁表和大頁(HugePage)。
    • 多級頁表就是把記憶體分成區塊來管理,將原來的對映關係改成區塊索引和區塊內的偏移。由於虛擬記憶體空間通常只用了很少一部分,那麼,多級頁表就只儲存這些使用中的區塊,這樣就可以大大地減少頁表的項數。
    • 大頁就是比普通頁更大的記憶體塊,常見的大小有 2MB 和 1GB。大頁通常用在使用大量記憶體的程序上,比如 Oracle、DPDK 等。

檢視記憶體使用情況

  • 常用工具:free、top
  • total 是總記憶體大小;
  • used 是已使用記憶體的大小,包含了共享記憶體;
  • free 是未使用記憶體的大小;
  • shared 是共享記憶體的大小;
  • buff/cache 是快取和緩衝區的大小;
  • available 是新程序可用記憶體的大小。
  • VIRT 是程序虛擬記憶體的大小,只要是程序申請過的記憶體,即便還沒有真正分配實體記憶體,也會計算在內;
  • RES 是常駐記憶體的大小,也就是程序實際使用的實體記憶體大小,但不包括 Swap 和共享記憶體;
  • SHR 是共享記憶體的大小,比如與其他程序共同使用的共享記憶體、載入的動態連結庫以及程式的程式碼段等;
  • %MEM 是程序使用實體記憶體佔系統總記憶體的百分比。
  • 注意點:
    • 第一,虛擬記憶體通常並不會全部分配實體記憶體。從上面的輸出,你可以發現每個程序的虛擬記憶體都比常駐記憶體大得多。
    • 第二,共享記憶體 SHR 並不一定是共享的,比方說,程式的程式碼段、非共享的動態連結庫,也都算在 SHR 裡。當然,SHR 也包括了程序間真正共享的記憶體。所以在計算多個程序的記憶體使用時,不要把所有程序的 SHR 直接相加得出結果。

Buffer/Cache

  • Buffers 是核心緩衝區用到的記憶體,對應的是 /proc/meminfo 中的 Buffers 值。

    • Buffers 是對原始磁碟塊的臨時儲存,也就是用來快取磁碟的資料,通常不會特別大(20MB 左右)。這樣,核心就可以把分散的寫集中起來,統一優化磁碟的寫入,比如可以把多次小的寫合併成單次大的寫等等。
  • Cache 是核心頁快取和 Slab 用到的記憶體,對應的是 /proc/meminfo 中的 Cached 與 SReclaimable 之和。

    • Cached 是從磁碟讀取檔案的頁快取,也就是用來快取從檔案讀取的資料。這樣,下次訪問這些檔案資料時,就可以直接從記憶體中快速獲取,而不需要再次訪問緩慢的磁碟。
    • SReclaimable 是 Slab 的一部分。Slab 包括兩部分,其中的可回收部分,用 SReclaimable 記錄;而不可回收部分,用 SUnreclaim 記錄。

記憶體分配器Slab(待續)