(诈尸氵一篇meminfo)
文章还处于work in progress状态,先直接从OneNote上复制过来吧
示例
meminfo的分类有:
MemTotal: 16642364 kB
MemFree: 9337232 kB
Buffers: 34032 kB
Cached: 188576 kB
SwapCached: 0 kB
Active: 167556 kB
Inactive: 157876 kB
Active(anon): 103104 kB
Inactive(anon): 17440 kB
Active(file): 64452 kB
Inactive(file): 140436 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 26214396 kB
SwapFree: 26120500 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 102824 kB
Mapped: 71404 kB
Shmem: 17720 kB
Slab: 13868 kB
SReclaimable: 6744 kB
SUnreclaim: 7124 kB
KernelStack: 2848 kB
PageTables: 2524 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 515524 kB
Committed_AS: 3450064 kB
VmallocTotal: 122880 kB
VmallocUsed: 21296 kB
VmallocChunk: 66044 kB
HardwareCorrupted: 0 kB
AnonHugePages: 2048 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 12280 kB
DirectMap4M: 897024 kB
公式换算
meminfo可以看mm模块的代码,虽然类型很多,但计算方式还算透明
内存类型 | 简化换算 | 其它备注 |
---|---|---|
MemTotal |
physical - .text | total并不是全部,需要抠掉一些kernel代码段的大小 |
MemFree |
lowFree + HighFree | HighFree基本就是0的意思 |
MemAvailable |
一个简单的估算方式是 所有zone的free 减去 low reserved 和 high watermark 加上 可回收的page cache 和 slab 这里的可回收是个估算值,可能直接取总数的1/2 | |
Buffers |
for each bdev: ret += bdev->bd_inode->i_mapping->nr_pages | 裸设备读写的临时存储 如果是文件系统操作则应对应于metadata,如inode,superblock 否则要算上直接读写bdev的mapping(本质就是bdev) |
Cached |
page cache, in-memory files only | 这里只算in-memory引起的 需要减去SwapCached和Buffers 可以认为代表文件映射的内存和tmpfs(shmem)映射(因为也是file-backed)的内存 |
SwapCached |
曾经换出,然后换入回来的内存,但是仍存在于swap文件 这是用于节省IO的,当已经换回来后,如果再次缺少内存,那就直接舍去这一部分,而不是换出回swap文件,从而节省IO | |
Active |
LRU中标记active,一般不reclaim,但也有可能 | |
Inactive |
LRU中标记inactive,很可能reclaim | |
HighTotal, HighFree |
~ | |
LowTotal, LowFree |
~ | |
SwapTotal |
~ | |
SwapFree |
已经被换出的内存,临时存储在disk | |
Dirty |
标记为dirty的内存,仍未写回 | |
Writeback |
正在写回的内存 | |
AnonPages |
映射到userspace页表的无后备文件的内存 | |
HardwareCorrupted |
~ | |
AnonHugePages |
~ | |
Mapped |
已经被mapped映射的文件 | |
Shmem |
shmem + tmpfs | |
ShmemHugePages |
||
ShmemPmdMapped |
||
KReclaimable |
SReclaimable + …direct allocations | kernel分配出来的,但可被reclaim的内存 |
Slab |
~ | |
SReclaimable |
part of Slab | Slab的一部分,允许reclaim |
SUnreclaim |
part of Slab | Slab的一部分,不允许reclaim |
PageTables |
~ | |
VmallocTotal |
vmalloc() | |
VmallocUsed |
used vmalloc() | |
VmallocChunk |
largest contiguous and free vmalloc() |
meminfo在具体的实现上,仍然是获取来自vmstat的全局变量信息
其实vmstat也是从kernel提供的API去更新值的,涉及到整个物理内存zone管理的细节
注:关于pagecache
在统计代码实现上,pagecache相当于active file LRU加上inactive file LRU
我觉得应该不只是这些,可能是个大概的值
而在接口层面,Cached成分相对复杂,是NR_FILE_PAGES - SwapCached - Buffers
这个NR_FILE_PAGES就是所有的mapping之和了,就是不确定是否等于上述的pagecache(两个LRU加起来)
有一种观点是Buffers + Cached = inactive(file) + active(file) + shmem
Shmem是算到Cached里面的
Buffers算是bdev files mapping特例排除掉
因此一个完整的pagecache = inactive(file) + active(file) + shmem,而上面available统计实现是为了快速估算没算上吧