聊聊 Linux 的内存统计( 三 )

apped项,因为前者中包括Unmapped的内存,后者还包含共享内存的部分(这部分在Inactive(anon)Active(anon)里) 。
这里有一个情况要注意,与文件关联的页也有可能是匿名页(MAP_PRIVATE映射的页面被修改时会产生一个匿名页拷贝),会被算到AnonPages里 。
与此相关的相关的统计项有:

  • AnonPages — 匿名页(Anonymous pages)的大小,同时也包含Transparent HugePages (THP)对应的 AnonHugePages
  • Mapped — 设备和文件等映射的大小,Mapped统计了Cached中所有的Mapped页面,是Cached的子集(满足Cached-Mapped=Unmapped) 。共享内存、可执行程序的文件、动态库、mmap的文件等都统计在这里
  • Shmem — 共享内存的大小,包括Shared Memorytmpfsdevtmpfs
注意 Linux 的内存是真正使用时才分配的,所以注意这里的大小都是已分配的大小,而不是程序里申请的大小 。
下面都是内核使用的内存相关的统计项:
  • Slab — 内核Slab结构使用的大小(就是那个Slab分配器占用的)
  • SReclaimable — 内核Slab里面可回收的部分(调用kmem_getpages()时带有 SLAB_RECLAIM_ACCOUNT 标的)
  • SUnreclaim — Slab里面无法回收的大小,等于Slab项 -SReclaimable
  • KernelStack — 分配给内核栈的大小(每个用户线程都会分配一个Kernel Stack,系统调用syscalltrapexception后进入内核态执行代码时候使用)
  • PageTables — 页表的大小(就是经常挂在嘴上的那个页表)
  • NFS_Unstable — 发送到服务端但尚未提交的 NFS 页的大小
  • Bounce — 块设备 “bounce buffers” 部分的大小(有些老设备只能访问低端内存,比如 16M 以下,这部分分配的 buffer 统计在这里)
  • WritebackTmp — FUSE 用于写回磁盘的缓冲区的大小
  • VmallocTotal — vmalloc 区域大小
  • VmallocUsed — vmalloc 区域使用大小
  • VmallocChunk — vmalloc 区域最大的 free 连续区块大小
  • HardwareCorrupted — 系统检测到内存的硬件故障的内存大小(问题页会被记录不再使用)
之前说过,HugePages 是独立统计的,如果进程使用了 HugePages,是不会计入自身的RSS/PSS的 。注意下面的AnonHugePages指的是透明大页(THP,Transparent HugePages),THP是统计在进程的RSS/PSS里的,要注意区别 。下面是相关的统计项:
  • AnonHugePages — 透明大页 THP 使用的大小
  • HugePages_Total — 内存大页的总量,对应 /proc/sys/vm/nr_hugepages,可以动态改
  • HugePages_Free — 内存大页中 free 的大小
  • HugePages_Rsvd — 内存大页中能分配出来的大小
  • HugePages_Surp — 内存大页中超过 /proc/sys/vm/nr_hugepages的大小,最大值由/proc/sys/vm/nr_overcommit_hugepages限制
  • Hugepagesize — 内存大页的页大小
 
进程级别的统计先介绍几个通用概念:
  • VSS - Virtual Set Size,虚拟内存大小,包含共享库占用的全部内存,以及分配但未使用内存
  • RSS - Resident Set Size,实际使用物理内存,包含了共享库占用的全部内存
  • PSS - Proportional Set Size,实际使用的物理内存,共享库占用的内存按照进程数等比例划分
  • USS - Unique Set Size,进程独自占用的物理内存,不包含共享库占用的内存
 
/proc/{pid}/smaps 文件在/proc/{pid}/smaps文件对应每个进程的详细内存分段统计 。截取一部分:
聊聊 Linux 的内存统计

文章插图
下面分别解释下含义: