2021-05-12 14:32:11
如何通過閱讀原始碼了解 vmstat 中的指標
vmstat -a 命令能看到 active memory 和 inactive memory,但是它們是什麼意思呢?
$ vmstat-a
procs -----------memory-------------swap-------io-----system--------cpu-----
r b swpd free inact active si so bi bo in cs us sy id wa st
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
中獲取的資料:
$ grep-i act /proc/meminfo
Active:1767928 kB
Inactive:1373760 kB
而/proc/meminfo
的資料是在以下核心函數中生成的:
fs/proc/meminfo.c:
==================
0023staticint meminfo_proc_show(struct seq_file *m,void*v)
0024{
...
0032unsignedlong pages[NR_LRU_LISTS];
...
0051for(lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
0052 pages[lru]= global_page_state(NR_LRU_BASE + lru);
...
0095"Active: %8lu kBn"
0096"Inactive: %8lu kBn"
0097"Active(anon): %8lu kBn"
0098"Inactive(anon): %8lu kBn"
0099"Active(file): %8lu kBn"
0100"Inactive(file): %8lu kBn"
...
0148 K(pages[LRU_ACTIVE_ANON]+ pages[LRU_ACTIVE_FILE]),
0149 K(pages[LRU_INACTIVE_ANON]+ pages[LRU_INACTIVE_FILE]),
0150 K(pages[LRU_ACTIVE_ANON]),
0151 K(pages[LRU_INACTIVE_ANON]),
0152 K(pages[LRU_ACTIVE_FILE]),
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
相關文章