Linux的内存分布图:ps:不知道图出自哪位大神之手如有侵权望请告知,谢谢
meminfo文件的部分内容解释:
MemTotal: 300000 kB
MemFree: 208224 kB
MemAvailable: 218744 kB
Buffers: 164 kB
Cached: 16304 kB
SwapCached: 0 kB
Active: 2900 kB
Inactive: 34828 kB
Active(anon): 1380 kB
Inactive(anon): 23196 kB
Active(file): 520 kB
Inactive(file): 11632 kB
Unevictable: 4 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 900 kB
Writeback: 0 kB
AnonPages: 20776 kB
Mapped: 6848 kB
Shmem: 4340 kB
KReclaimable: 612 kB
Slab: 2792 kB
SReclaimable: 612 kB
SUnreclaim: 1180 kB
KernelStack: 456 kB
PageTables: 156 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 150420 kB
Committed_AS: 414592 kB
VmallocTotal: 159040 kB
VmallocUsed: 496 kB
VmallocChunk: 0 kB
Percpu: 016 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
FileHugePages: 0 kB
FilePmdMapped: 0 kB
CmaTotal: 2144 kB
CmaFree: 2584 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 08 kB
Hugetlb: 0 kB
以上是一个文件示例
MemTotal:除去BIOS要保留的部分内存之外,剩下可供kernel支配的内存。
MemFree:还未被使用的内存,注意它不能代表全部可用的内存。
MemAvailable:在MemFree的基础上加上cache/buffer/slab这一部分可以收回的内存。这是一个估值,并不是特别的精确。
Buffers:文件缓冲区内存。
Cached:高速缓存器的内存。
SwapCached:高速缓存器的交换内存。
Active:活跃使用的缓存或高速缓存的页。
Inactive:不常用的缓存或高速缓存的页。
匿名内存是指那些不与文件系统上的文件直接关联的内存页,例如进程的堆和栈。这些内存页通常用于存储进程的动态数据,如变量和函数调用的返回地址等。活跃的匿名内存是指最近被访问过的匿名内存页,因此它们更有可能继续被访问,而不是被交换到磁盘上
Active(anon):活跃的匿名内存。
Inactive(anon):不活跃的匿名内存。(优先会被回收)
Active(file):活跃的文件。
Inactive(file):不活跃的文件。(优先会被回收)
Unevictable:不能被交换出内存。
大致包含几种情况:
-
被mlock()锁定的内存页:当应用程序使用mlock()系统调用锁定内存页时,这些页不能被交换出去,因为它们包含对应用程序至关重要的数据,如共享内存段或程序的代码段。
-
共享内存:使用系统V共享内存API(如shmget, shmat)或POSIX共享内存API(如shm_open, mmap)创建的共享内存区域,如果被锁定(例如通过SHM_LOCK),也会成为Unevictable内存的一部分。
-
ramfs:某些情况下,ramfs(一种内存文件系统)也会占用Unevictable内存,因为它通常被用作临时存储,并且需要保持在内存中以便快速访问。
Unevictable
内存的存在意味着这部分内存不能被系统回收利用,即使在内存压力较大的情况下。这通常不会对系统性能产生负面影响,但如果Unevictable
的值异常高,可能表明系统内存管理存在问题,需要进一步分析和优化。
需要注意的是,Unevictable
内存并不包括所有的锁定内存,例如,通过mlockall()系统调用锁定的内存页,如果设置了MCL_FUTURE标志,则这些内存页仍然可以被交换出去。此外,Unevictable
内存的大小可能会随着系统运行和内存管理策略的变化而变化。
Mlocked: 锁定在物理内存中的内存量。这些内存页不会被交换到磁盘上,即使系统内存不足时也不会被回收。
SwapTotal:字段表示系统配置的交换空间的总量。
SwapFree:字段表示系统配置的交换空间的空余量。
Dirty:当前内存中已被修改但尚未写入磁盘的内存页的大小。
Writeback:当前正在被写回到磁盘的内存页的大小。
AnonPages:匿名页的数量。
匿名页的使用一般包含以下场景:
-
动态内存分配:当进程使用
malloc
或mmap
(带有MAP_ANONYMOUS
标志)分配内存时,这些内存页不会被映射到任何文件上,而是作为匿名页存在。 -
进程堆和栈:进程的堆和栈通常也是匿名页,因为它们不与文件直接关联。
-
共享内存:通过
mmap
创建的共享内存区域,如果是匿名共享内存,也会使用匿名页。 -
代码和数据:进程的代码段和数据段在某些情况下也可能使用匿名页。
Mapped:表示被映射到用户进程地址空间的文件-backed pages的数量。
文件-backed page一般指:
- 共享库:用户空间程序通常会映射一些共享库,如动态链接库(dynamic shared objects, DSOs)或动态链接库(dynamic link libraries, DLLs)。
- 可执行文件:程序的可执行代码通常也会被映射到内存中。
- 内存映射文件:使用
mmap
创建的内存映射文件,这些文件直接与磁盘上的文件内容相对应。
Shmem:表示系统当前使用的共享内存的大小。共享内存(Shared Memory)是进程间通信(IPC)的一种方式,允许多个进程访问同一块内存区域。
Shmem
统计的内容包括:
- System V共享内存:通过
shmget
、shmat
、shmdt
和shmctl
系统调用进行操作的共享内存。 - POSIX共享内存:通过
shm_open
、mmap
和munmap
系统调用进行操作的共享内存。 - tmpfs和devtmpfs:tmpfs是一种基于内存的文件系统,通常挂载在
/dev/shm
目录,它实际上也是通过共享内存机制实现的。devtmpfs是用于设备节点的自动创建和删除的内存文件系统。 - 匿名共享内存:通过
mmap
系统调用分配的带有MAP_SHARED
和MAP_ANONYMOUS
标志的内存区域。
KReclaimable:表示内核中可回收的内存数量。
Slab:内核中用于管理内存分配和释放的总量。也是一种缓存机制,它用于存储内核数据结构,如进程描述符、文件对象等。
SReclaimable:和KReclaimable相同。
SUnreclaim:表示内核中不可回收的内存数量。
KernelStack:表示为每个用户线程分配的内核栈消耗的内存页数。
PageTables:表示当前系统中用于管理内存分页的页表所消耗的内存页数。
NFS_Unstable:表示那些已经发送给NFS服务器但还没有稳定写入磁盘的内存页的大小。
Bounce:表示用于块设备"bounce buffers"的内存量。
Bounce buffers是一种内核使用的技术,它允许不能直接访问高端内存的旧式硬件(例如,只能访问低16MB内存的ISA设备)与现代系统(可能有大量内存)之间进行数据交换。
WritebackTmp:表示由FUSE(Filesystem in Userspace)用于临时写回缓冲区的内存量。
FUSE是一种允许用户空间程序提供文件系统功能的接口,它通过在用户空间运行的守护进程来处理文件系统操作,而不是在内核空间。
CommitLimit:表示系统允许的内存分配的总量,包括已分配但尚未使用的内存。
Committed_AS:表示当前所有进程已经申请的内存总大小,这个值包括了所有进程的虚拟内存空间的总和,即使这些内存实际上还没有被使用。
ps:如果这个值接近系统的CommitLimit
,这意味着系统已经承诺了大量的内存分配,如果进程实际使用更多的内存,可能会导致系统内存紧张,甚至触发OOM(Out-Of-Memory)killer来终止一些进程以释放内存。
VmallocTotal:表示系统可以用于vmalloc
分配的总虚拟内存大小。
VmallocUsed:表示系统已经使用的vmalloc
的虚拟内存大小。
VmallocChunk:表示当前最大的连续未分配的vmalloc
内存块大小。
Percpu:表示为每个CPU核心保留的内存量,这部分内存通常用于存储每个CPU的页表、内核栈等数据结构。
HardwareCorrupted:表示由于硬件故障而被系统识别并删除的内存页的总大小。
AnonHugePages:表示当前系统中使用的匿名透明大页(Transparent HugePages,THP)的数量。
THP——透明大页是Linux内核中的一个特性,它可以自动将小页面(通常为4 KB)合并成大页面(通常为2 MB或更大),以此来减少内存访问页表项PTE(Page Table Entries)的大小和访问次数,减轻了转译后备缓冲器TLB(Translation Lookaside Buffer)缓存的压力,提高内存访问的效率。
透明大页目前主要适用于匿名内存映射和tmpfs/shmem
,但未来可能会扩展到其他文件系统。透明大页的设计允许系统在没有足够连续小页的情况下,优雅地回退到使用小页,而不需要用户空间的干预。这种自动提升和降级页面大小的特性,使得透明大页在提高性能的同时,也具有很好的兼容性和灵活性。
ShmemHugePages:表示当前系统中用于System V共享内存和某些类型的tmpfs内存映射的透明大页的数量。
ShmemPmdMapped:表示由透明大页支持的、被映射到用户空间的共享内存(如tmpfs或System V共享内存)的内存使用量。
FileHugePages:表示使用大页机制的文件缓存(page cache)所占用的内存大小。
FilePmdMapped:表示在用户空间中分配了大页面的映射页面缓存所消耗的内存大小。
CmaTotal:表示系统预留的用于连续内存分配(Contiguous Memory Allocator,CMA)的总内存量。
CMA是Linux内核的一个特性,它允许内核预留一块物理内存区域,用于分配大块的连续内存页,这对于某些需要连续内存的硬件设备(如某些图形处理器、视频编解码器等)是必要的。
CmaFree:表示当前系统中连续内存分配器未使用的内存大小。
HugePages_Total:表示系统中配置的HugePage总数。
HugePages_Free:表示当前空闲的HugePage数量。
HugePages_Rsvd:表示为HugePage保留的内存页。
HugePages_Surp:表示超出系统默认配置的额外大页内存数量。
Hugepagesize:表示HugePage的大小。
Hugetlb:表示系统配置的大页内存页的大小。
本文仅用于自己学习记录使用,谢谢。如有错误感谢指正。