解读vmstat
中的ACTIVE/INACTIVE MEMORY
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
1 0 138096 319560 1372408 1757848 0 0 2 3 2 3 1 0 99 0 0
但它们的含义在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: ==================
0023 static int meminfo_proc_show(struct seq_file *m, void *v)
0024 {
... 0032 unsigned long pages[NR_LRU_LISTS]; ... 0051 for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
0052 pages[lru] = global_page_state(NR_LRU_BASE + lru);
... 0095 "Active: %8lu kB\n" 0096 "Inactive: %8lu kB\n" 0097 "Active(anon): %8lu kB\n" 0098 "Inactive(anon): %8lu kB\n" 0099 "Active(file): %8lu kB\n" 0100 "Inactive(file): %8lu kB\n"
... 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 kernel
的内存页面回收算法(Page Frame Reclaiming Algorithm
)所使用的数据结构,LRU
是Least Recently Used
的缩写词,这个算法的核心思想是:回收的页面应该是最近使用得最少的,为了实现这个目标,最理想的情况是每个页面都有一个年龄项,用于记录最近一次访问页面的时间,可惜x86 CPU
硬件并不支持这个特性,x86 CPU
只能做到在访问页面时设置一个标志位Access Bit
,无法记录时间,所以Linux Kernel
使用了一个折衷的方法——它采用了LRU list
列表,把刚访问过的页面放在列首,越接近列尾的就是越长时间未访问过的页面,这样,虽然不能记录访问时间,但利用页面在LRU list
中的相对位置也可以轻松找到年龄最长的页面。Linux kernel
设计了两种LRU list: active list
和 inactive list
, 刚访问过的页面放进active list
,长时间未访问过的页面放进inactive list
,这样从inactive list
回收页面就变得简单了。内核线程kswapd
会周期性地把active list
中符合条件的页面移到inactive list
中,这项转移工作是由refill_inactive_zone()
完成的。
解读vmstat
中的ACTIVE/INACTIVE MEMORY
解读vmstat
中的ACTIVE/INACTIVE MEMORY
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
在发生换页时,是对交换区进行读/写操作。