环境
- Red Hat Enterprise Linux(所有版本)
问题
- 我需要一个解释
/proc/meminfo
输出。 - 我想比较一下
free -k
到cat /proc/meminfo
.
解决
- 对于的定义
/proc/meminfo
RHEL 5之前的Red Hat Enterprise Linux (RHEL)版本中的字段,请查看/proc/meminfo中的每个值表示什么? - 的每个领域
cat /proc/meminfo
将在中讨论诊断步骤. - RHEL 5的输出在某些设置上有所不同。这也在诊断步骤.
- RHEL 5也有一些RHEL 6中不再存在的字段。关于这个问题的解释,请看x86_64 RHEL 6上的/proc/meminfo中为什么缺少LowTotal、LowFree、HighTotal和HighFree?
- 有关输出的更多信息
free
命令参见如何在Red Hat Enterprise Linux中查看系统内存利用率? - RHEL 7和更高版本有一个附加字段,称为
MemAvailable
在/proc/meminfo
- RHEL 7和更高版本的输出略有变化
free
命令
【文章福利】小编推荐自己的Linux内核源码交流群:【869634926】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!
Linux内存总览图
meminfo参数的详细介绍
/proc/meminfo是了解Linux系统内存使用状况的主要接口,我们最常用的”free”、”vmstat”等命令就是通过它获取数据的 ,/proc/meminfo所包含的信息比”free”等命令要丰富得多,然而真正理解它并不容易,比如我们知道”Cached”统计的是文件缓存页,manpage上说是“In-memory cache for files read from the disk (the page cache)”,那为什么它不等于[Active(file)+Inactive(file)]?AnonHugePages与AnonPages、HugePages_Total有什么联系和区别?很多细节在手册中并没有讲清楚,本文对此做了一点探究。
负责输出/proc/meminfo的源代码是:
fs/proc/meminfo.c : meminfo_proc_show()
MemTotal: 3809036 kB
MemFree: 282012 kB
MemAvailable: 865620 kB
Buffers: 0 kB
Cached: 854972 kB
SwapCached: 130900 kB
Active: 1308168 kB
Inactive: 1758160 kB
Active(anon): 1010416 kB
Inactive(anon): 1370480 kB
Active(file): 297752 kB
Inactive(file): 387680 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 4063228 kB
SwapFree: 3357108 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 2104412 kB
Mapped: 40988 kB
Shmem: 169540 kB
Slab: 225420 kB
SReclaimable: 134220 kB
SUnreclaim: 91200 kB
KernelStack: 5936 kB
PageTables: 35628 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 5967744 kB
Committed_AS: 5626436 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 351900 kB
VmallocChunk: 34359363652 kB
HardwareCorrupted: 0 kB
AnonHugePages: 139264 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 204484 kB
DirectMap2M: 3915776 kB
MemTotal
系统从加电开始到引导完成,firmware/BIOS要保留一些内存,kernel本身要占用一些内存,最后剩下可供kernel支配的内存就是MemTotal。这个值在系统运行期间一般是固定不变的。可参阅解读DMESG中的内存初始化信息。
MemFree
表示系统尚未使用的内存。[MemTotal-MemFree]就是已被用掉的内存。
MemAvailable
有些应用程序会根据系统的可用内存大小自动调整内存申请的多少,所以需要一个记录当前可用内存数量的统计值,MemFree并不适用,因为MemFree不能代表全部可用的内存,系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以这部分可回收的内存加上MemFree才是系统可用的内存,即MemAvailable。/proc/meminfo中的MemAvailable是内核使用特定的算法估算出来的,要注意这是一个估计值,并不精确。
内存黑洞
追踪Linux系统的内存使用一直是个难题,很多人试着把能想到的各种内存消耗都加在一起,kernel text、kernel modules、buffer、cache、slab、page table、process RSS…等等,却总是与物理内存的大小对不上,这是为什么呢?因为Linux kernel并没有滴水不漏地统计所有的内存分配,kernel动态分配的内存中就有一部分没有计入/proc/meminfo中。
我们知道,Kernel的动态内存分配通过以下几种接口:
alloc_pages/__get_free_page: 以页为单位分配
vmalloc: 以字节为单位分配虚拟地址连续的内存块
slab allocator
kmalloc: 以字节为单位分配物理地址连续的内存块,它是以slab为基础的,使用slab层的general caches — 大小为2^n,名称是kmalloc-32、kmalloc-64等(在老kernel上的名称是size-32、size-64等)。
通过slab层分配的内存会被精确统计,可以参见/proc/meminfo中的slab/SReclaimable/SUnreclaim;
通过vmalloc分配的内存也有统计,参见/proc/meminfo中的VmallocUsed 和 /proc/vmallocinfo(下节中还有详述);
而通过alloc_pages分配的内存不会自动统计,除非调用alloc_pages的内核模块或驱动程序主动进行统计,否则我们只能看到free memory减少了,但从/proc/meminfo中看不出它们具体用到哪里去了。比如在VMware guest上有一个常见问题,就是VMWare ESX宿主机会通过guest上的Balloon driver(vmware_balloon module)占用guest的内存,有时占用得太多会导致guest无内存可用,这时去检查guest的/proc/meminfo只看见MemFree很少、但看不出内存的去向,原因就是Balloon driver通过alloc_pages分配内存,没有在/proc/meminfo中留下统计值,所以很难追踪。
比较输出
free -k
产量(RHEL 5和RHEL 6):
total used free shared buffers cached
Mem: 7778104 2971960 4806144 0 211756 1071092
-/+ buffers/cache: 1689112 6088992
Swap: 4194296 0 4194296
free -k
输出(RHEL 7和更高版本):
total used free shared buff/cache available
Mem: 1012952 252740 158732 11108 601480 543584
Swap: 1048572 5380 1043192
- 相关字段来自
/proc/meminfo
将它们与的输出进行匹配free -k
:
MemTotal: 7778104 kB
MemFree: 4806144 kB
Buffers: 211756 kB
Cached: 1071092 kB
SwapTotal: 4194296 kB
SwapFree: 4194296 kB
- 对于RHEL 7和更高版本,有一个额外的可用字段,用于代替的计算
-/+ buffers/cache
线路:
MemAvailable: 543584 kB
匹配输出free -k
到/proc/meminfo
下表显示了如何获取free
输出与匹配/proc/meminfo
Red Hat Enterprise Linux 5、6、7、8和9中的字段。
free output | 对应的/proc/meminfo ֶ |
---|---|
Mem: total | MemTotal |
Mem: used | MemTotal - MemFree |
Mem: free | MemFree |
Mem: shared(现如今可以忽略。它没有任何意义。) | 不适用的 |
Mem: buffers | Buffers |
Mem: cached | Cached |
-/+ buffers/cache: used | MemTotal - (MemFree + Buffers + Cached) |
-/+ buffers/cache: free | MemFree + Buffers + Cached |
Swap: total | SwapTotal |
Swap: used | SwapTotal - SwapFree |
Swap: free | SwapFree |
下表显示了如何获取free
输出与匹配/proc/meminfo
Red Hat Enterprise Linux 7.1或更高版本(procps-ng 3.3.10)中的字段。
free output | 对应的/proc/meminfo ֶ |
---|---|
Mem: total | MemTotal |
Mem: used | MemTotal - MemFree - Buffers - Cached - Slab |
Mem: free | MemFree |
Mem: shared | Shmem |
Mem: buff/cache | Buffers + Cached + Slab |
Mem:available | MemAvailable |
Swap: total | SwapTotal |
Swap: used | SwapTotal - SwapFree |
Swap: free | SwapFree |
根本原因
- 分析内存消耗
诊断步骤
大多数内容取自内核文档(Documentation/filesystems/proc.txt
和Documentation/vm/hugetlbpage.txt
)
高级统计
RHEL 5、6、7、8和9。
MemTotal:
总可用内存MemFree:
物理内存的数量不由系统使用Buffers:
缓冲区缓存中的内存,因此相对临时存储原始磁盘块。这不应该变得很大。Cached:
页面缓存中的内存(磁盘缓存和共享内存)SwapCached:
既存在于主存中,也存在于交换文件中的内存。(如果需要内存,该区域不需要再次换出,因为它已经在交换文件中。如果机器内存不足,这可以节省I/O并提高性能。)
仅RHEL 7、8和9
MemAvailable:
在不交换的情况下,估计有多少内存可用于启动新的应用程序。- 有关的更多信息
MemAvailable
,请检查这里.
- 有关的更多信息
详细级别统计
RHEL 5、6、7、8和9。
Active:
最近使用较多且通常不会换出或回收的内存Inactive:
拥有的记忆不最近使用过,可以换出或回收
RHEL 6,7,8和9。
Active(anon):
最近使用较多且通常不会被换出的匿名内存Inactive(anon):
匿名记忆不最近使用过,可以换出Active(file):
最近使用的页面缓存内存,通常在需要时才回收Inactive(file):
可以回收而不会对性能产生巨大影响的页面缓存内存Unevictable:
由于各种原因,无法检索的页面不能被换出Mlocked:
使用锁定到内存的页面mlock()
系统调用。Mlocked页面也是不可检索的。
内存统计
RHEL 5、6、7、8和9。
SwapTotal:
可用的总交换空间SwapFree:
剩余的可用交换空间Dirty:
等待写回磁盘的内存Writeback:
主动写回磁盘的内存AnonPages:
映射到用户空间页表的非文件备份页Mapped:
已映射的文件,如库Slab:
内核数据结构缓存PageTables:
专用于最低级别页表的内存量。如果许多进程都连接到同一个共享内存段,这个值可能会增加到很高。NFS_Unstable:
NFS页面已发送到服务器,但尚未提交到存储Bounce:
用于块设备的存储器bounce buffers
CommitLimit:
基于过量使用比率(vm.overcommit_ratio
),这是系统上当前可分配的内存总量。仅当启用了严格的超量承诺会计时,才会遵守此限制(中的模式2vm.overcommit_memory
).Committed_AS:
系统上当前分配的内存量。提交的内存是由进程分配的所有内存的总和,即使它还没有被它们“使用”。VmallocTotal:
vmalloc存储区的总大小VmallocUsed:
使用的vmalloc区域的数量VmallocChunk:
vmalloc区域中空闲的最大连续块HugePages_Total:
内核分配的大页面数量(用vm.nr_hugepages
)HugePages_Free:
进程未分配的大页面数HugePages_Rsvd:
已承诺从池中进行分配但尚未进行分配的大型页面的数量。Hugepagesize:
的大小hugepage
(在基于英特尔的系统上通常为2MB)Percpu:
专用于每cpu对象的内存量。为了可伸缩性和内存访问速度的优化,许多特定于内核的对象被分解为系统中每个CPU都有一个该对象的副本。这些对象可以在启动时静态分配,也可以在系统运行时动态分配;例如,cgroups经常创建动态的每cpu对象分配。
RHEL 9
CmaTotal:
为当前内核保留的连续内存区域的总量。CmaFree:
当前内核可以自由使用的连续内存区域。
注意:的/proc/meminfo中添加了新参数RHEL 9
如同CmaTotal
& CmaFree
RHEL 6,7,8和9。
Shmem:
使用的共享内存总量(在多个进程之间共享,因此包括RAM磁盘、SYS-V-IPC和BSD,如SHMEM)SReclaimable:
可能被回收的板部分(如缓存)SUnreclaim:
在内存压力下无法回收的那部分板KernelStack:
内核堆栈使用的内存。这是不可回收的。WritebackTmp:
FUSE用于临时写回缓冲区的内存HardwareCorrupted:
内核识别为损坏/不工作的RAM数量AnonHugePages:
映射到用户空间页表的非文件备份的大页面HugePages_Surp:
池中大于中的值的大页数vm.nr_hugepages
剩余页面的最大数量由以下因素控制vm.nr_overcommit_hugepages
.DirectMap4k:
映射到4k大小页面的内核空间的内存量。DirectMap2M:
用2MB大小的页面映射到内核空间的内存量。DirectMap1G.
用1GB大小的页面映射到内核空间的内存量。
注释:DirectMap*
:在64位体系结构中,所有RAM都直接映射到内核空间。如果可能的话,内核使用更大的页面来提高TLB的效率。所以总和DirectMap*
如果RAM的数量不变,并且使用了大部分内存,则应该是常量DirectMap1G
和/或DirectMap2M
这与hugepages
.
注释:DirectMap1G
:该值仅在中可用/proc/meminfo
只要相应的CPU硬件支持它。您可以通过检查中的标志“pdpe1gb”来验证这一点/proc/cpuinfo
.