1. /proc/meminfo
/prox/meminfo
是Linux
系统统计内存状态非常重要的接口,上层的free
亦或者Android
系统的lmk
读取内存信息都来源于这个接口,其实现也非常简单,就是将内核中记录的各种内核数据打印出来,内存信息也非常全!
如下是kernel-5.10
版本输出的信息:
MemTotal: 7334508 kB
MemFree: 1327068 kB
MemAvailable: 3464796 kB
Buffers: 2016 kB
Cached: 1888764 kB
SwapCached: 5848 kB
Active: 776884 kB
Inactive: 1769432 kB
Active(anon): 406908 kB
Inactive(anon): 394548 kB
Active(file): 369976 kB
Inactive(file): 1374884 kB
Unevictable: 128488 kB
Mlocked: 127256 kB
SwapTotal: 6291452 kB
SwapFree: 4613628 kB
Dirty: 740 kB
Writeback: 0 kB
AnonPages: 779480 kB
Mapped: 584580 kB
Shmem: 20476 kB
KReclaimable: 782960 kB
Slab: 504928 kB
SReclaimable: 128860 kB
SUnreclaim: 376068 kB
KernelStack: 74848 kB
ShadowCallStack: 18792 kB
PageTables: 129676 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 9958704 kB
Committed_AS: 141040480 kB
VmallocTotal: 262930368 kB
VmallocUsed: 193260 kB
VmallocChunk: 0 kB
Percpu: 10336 kB
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
FileHugePages: 4096 kB
FilePmdMapped: 4096 kB
CmaTotal: 483328 kB
CmaFree: 139088 kB
MemTotal
上面提到,/proc/meminfo输出的是内核记录的内存信息,其和实际的物理内存信息是有差异的,MemTotal指的是内存管理的总物理内存,比如我这个设备配置的是8G的内存,但是其输出的总内存只有7334508,这是因为本身OS进行内存管理就需要占用到一定的内存,可参考memblock内存管理模块。内核通过_totalram_pages原子变量记录。
MemFree
系统中可以立即被使用的内存。
MemAvailable
系统可用内存,跟MemFree是有区分的,因为内核的一些缓存以及swap机制,部分内存可以通过”丢弃“、回写或者压缩,交换等动作而回收,然而,精确的判断系统可用内存是非常困难的,也并不需要精确判断,因为系统内存一直都是一个动态调整的过程,所以Linux内核采用一种估算的方法,估算的算法也非常简单,如下是kernel-5.10估算系统可用内存的方法:
long si_mem_available(void)
{
long available;
unsigned long pagecache;
unsigned long wmark_low = 0;
unsigned long pages[NR_LRU_LISTS];
unsigned long reclaimable;
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 += low_wmark_pages(zone);
/*
* Estimate the amount of memory available for userspace allocations,
* without causing swapping.
*/
available = global_zone_page_state(NR_FREE_PAGES) - totalreserve_pages;
/*
* Not all the page cache can be freed, otherwise the system will
* start swapping. Assume at least half of the page cache, or the
* low watermark worth of cache, needs to stay.
*/
pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
pagecache -= min(pagecache / 2, wmark_low);
available +&