关于Meminfo中MemAvailable 理解
我们知道linux提供了proc文件系统可以给用户查看一些系统信息,其中与内存相关的文件包含如下:
- /proc/meminfo
- /proc/zoneinfo
- /proc/vmstat
- /proc/buddyinfo
- /proc/sys/vm/
上述这些内容就是我们在遇到一些压测类问题时常看的内容,本部分内容介绍对于meminfo中的MemAvailable字段的理解;
本文主要介绍如下内容:
- MemAvailable计算过程中相关的概念理解说明,包含managed_pages、min_free_kbytes、watermark等
- MemAvailable的计算过程;
- 系统提供了哪些文件接口可以调整其大小?
1. MemAvailable 的用处
首先来看meminfo中的内容:
我们主要会关注三个主要指标:total、free和available:
- MemTotal 用于描述受kernel管理的所有内存项;
- MemFree 用于描述系统中处于Free状态的内存项;
- MemAvailable 用于描述系统中可供分配的内存项,注意这一项是一个估测值,其中包含Free和可回收的一部分内存项;
一般来说我们认为available项还有空间的话说明系统还处于一个正常状态,那么Avialable这一项是怎样算出来的呢?
2. MemAvailable的计算
我们先回答第一个问题,即Available这一项是如何计算出来的,直接上code:
available = si_mem_available(); //计算获取到available
...
show_val_kb(m, "MemAvailable: ", available); //将其显示出来
//具体来看 si_mem_available()的实现:/mm/page_alloc.c
long si_mem_available(void)
{
long available;
unsigned long pagecache;
unsigned long wmark_low = 0;
unsigned long pages[NR_LRU_LISTS];
struct zone *zone;
int lru;
for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
pages[lru] = global_node_page_state(NR_LRU_BASE + lru);
for_each_zone(zone)
wmark_low += zone->watermark[WMARK_LOW];//遍历zonelist获取每个zone的watermark值
available = global_page_state(NR_FREE_PAGES) - totalreserve_pages;//free - reserve
//注意这里reserve指的是各个zone中的lowmem部分和watermark[high]部分
//接下来计算pagecache中可回收的部分,这里回收FILE部分而未计算anoy部分是基于处理效率的考虑,anoy部分需要swap申请buffer以及emmc空间写入,而file只需要discard或者writeback即可;
pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
pagecache -= min(pagecache / 2, wmark_low);//取一半和wmark_low中较小的那个去除;
available += pagecache;
//接下来计算slab分配器分配内容中可回收的部分
available += global_page_state(NR_SLAB_RECLAIMABLE) - min(global_page_state(NR_SLAB_RECLAIMABLE)