首頁 > 軟體

如何通過閱讀原始碼了解 vmstat 中的指標

2020-06-16 17:46:43

vmstat -a 命令能看到 active memory 和 inactive memory,但是它們是什麼意思呢?

  1. $ vmstat-a
  2. procs -----------memory-------------swap-------io-----system--------cpu-----
  3. r b swpd free inact active si so bi bo in cs us sy id wa st
  4. 1013809631956013724081757848002323109900

它們的含義在 manpage 中只給了簡單的說明,並未詳細解釋:

inact: the amount of inactive memory. (-a option)
active: the amount of active memory. (-a option)

在此我們試圖準確理解它的含義。通過閱讀 vmstat 的原始碼 (vmstat.c 和 proc/sysinfo.c)得知,vmstat 命令是直接從 /proc/meminfo 中獲取的資料:

  1. $ grep-i act /proc/meminfo
  2. Active:1767928 kB
  3. Inactive:1373760 kB

/proc/meminfo 的資料是在以下核心函數中生成的:

  1. fs/proc/meminfo.c:
  2. ==================
  3. 0023staticint meminfo_proc_show(struct seq_file *m,void*v)
  4. 0024{
  5. ...
  6. 0032unsignedlong pages[NR_LRU_LISTS];
  7. ...
  8. 0051for(lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
  9. 0052 pages[lru]= global_page_state(NR_LRU_BASE + lru);
  10. ...
  11. 0095"Active: %8lu kBn"
  12. 0096"Inactive: %8lu kBn"
  13. 0097"Active(anon): %8lu kBn"
  14. 0098"Inactive(anon): %8lu kBn"
  15. 0099"Active(file): %8lu kBn"
  16. 0100"Inactive(file): %8lu kBn"
  17. ...
  18. 0148 K(pages[LRU_ACTIVE_ANON]+ pages[LRU_ACTIVE_FILE]),
  19. 0149 K(pages[LRU_INACTIVE_ANON]+ pages[LRU_INACTIVE_FILE]),
  20. 0150 K(pages[LRU_ACTIVE_ANON]),
  21. 0151 K(pages[LRU_INACTIVE_ANON]),
  22. 0152 K(pages[LRU_ACTIVE_FILE]),
  23. 0153 K(pages[LRU_INACTIVE_FILE]),

這段程式碼的意思是統計所有的 LRU list,其中 Active Memory 等於 ACTIVE_ANON 與 ACTIVE_FILE 之和,Inactive Memory 等於 INACTIVE_ANON 與 INACTIVE_FILE 之和。

LRU list 是 Linux 核心的記憶體頁面回收演算法(Page Frame Reclaiming Algorithm)所使用的資料結構,LRU 是 Least Recently Used 的縮寫詞。這個演算法的核心思想是:回收的頁面應該是最近使用得最少的

為了實現這個目標,最理想的情況是每個頁面都有一個年齡項,用於記錄最近一次存取頁面的時間,可惜 x86 CPU 硬體並不支援這個特性,x86 CPU 只能做到在存取頁面時設定一個標誌位 Access Bit,無法記錄時間。

所以 Linux 核心使用了一個折衷的方法:它採用了 LRU list 列表,把剛存取過的頁面放在列首,越接近列尾的就是越長時間未存取過的頁面,這樣,雖然不能記錄存取時間,但利用頁面在 LRU list 中的相對位置也可以輕鬆找到年齡最長的頁面。

Linux 核心設計了兩種 LRU list: active list 和 inactive list, 剛存取過的頁面放進 active list,長時間未存取過的頁面放進 inactive list,這樣從 inactive list 回收頁面就變得簡單了。核心執行緒 kswapd 會周期性地把 active list 中符合條件的頁面移到 inactive list 中,這項轉移工作是由 refill_inactive_zone() 完成的。這段程式碼的意思是統計所有的 LRU list,其中Active Memory 等於 ACTIVE_ANON 與 ACTIVE_FILE 之和,Inactive Memory 等於 INACTIVE_ANON 與 INACTIVE_FILE 之和。

LRU list 示意圖

LRU_list

vmstat 看到的 active/inactive memory 就分別是 active list 和 inactive list 中的記憶體大小。如果 inactive list 很大,表明在必要時可以回收的頁面很多;而如果 inactive list 很小,說明可以回收的頁面不多。

Active/inactive memory 是針對使用者進程所佔用的記憶體而言的,核心佔用的記憶體(包括 slab)不在其中。

至於在原始碼中看到的 ACTIVE_ANON 和 ACTIVE_FILE,分別表示 anonymous pages 和 mapped pages。使用者進程的記憶體頁分為兩種:與檔案關聯的記憶體(比如程式檔案、資料檔案所對應的記憶體頁)和與檔案無關的記憶體(比如進程的堆疊,用 malloc 申請的記憶體),前者稱為 file pages 或 mapped pages,後者稱為 anonymous pages。file pages 在發生換頁(page-in 或 page-out)時,是從它對應的檔案讀入或寫出;anonymous pages 在發生換頁時,是對交換區進行讀/寫操作。

本文永久更新連結地址http://www.linuxidc.com/Linux/2016-01/127867.htm


IT145.com E-mail:sddin#qq.com