目录
初识 SMAPS 机制
SMAPS 通识知识
File-Mapping and Anonymous-Mappin
Shared and Private Area
CLEAN and Dirty Area
RSS and SWAP
PSS(Proportional Set Size)
Reference and Access Young
LOCKED Memory
Hugetlbfs Huge Page
THP: Transparent Huge Page
VMFlags
SMAPS 数据结构
SMAPS 源码分析
SMAPS ROLLUP 机制
SMAPS 机制实践
SMAPS 机制使用
查看指定进程的 SMAPS 文件
查看指定进程匿名内存总和
查看指定进程 RSS 总和
查看指定进程共享内存总和
查看指定进程私有内存(独占内存)总和
查看指定进程内存映射大小总和
查看指定进程堆内存使用情况
查看指定进程栈内存使用情况
查看指定进程 PSS 总和
查看指定进程 SWAP 总和
查看指定进程最大内存映射
查看指定进程最大 RSS 映射区
查看指定进程最大 PSS 映射区
查看指定进程 VMFLAGS 信息
查看指定进程使用最多 SWAP 映射
查看指定进程所有匿名映射
查看指定进程 writeable 映射
查看指定进程 ReadOnly 映射
查看指定进程找出最常用的内存权限模式
查看指定进程所有映射地址
查看指定进程最大 KernelPageSize 的映射
查看指定进程没有关联文件的区域
查看指定进程透明大页的总和
查看指定进程 Hugetlb 大页的总和
查看使用透明大页的进程
查看使用 Hugetlb 大页的进程
PROC SMAPS 通识知识
PROC SMAPS 机制用于获得进程所有用户空间虚拟区域的信息,这些信息主要来自虚拟内存映射物理内存的页表、虚拟内存映射物理内存对应的 struct page 数据结构,以及虚拟内存区域对应的 struct vm_area_struct 数据结构. SMAPS 机制从获得这些数据之后,处理之后按一定模式从 seq_file 输出到用户空间. 那么个字段的含义:
- 6000000000-6000001000: 用于描述该虚拟区域的范围.
- rw-p: r 表示虚拟区可读,w 表示虚拟区可写,x 表示虚拟区域可执行; s 表示虚拟区采用共享映射,p 表示虚拟区采用私有映射.
- 00000000: 表示该区域距离 VMA 起始位置的距离.
- 00:00 0: MAJOR:MINOR 与 ino.
- Size: 表示虚拟区域里虚拟内存的大小.
- KernelPageSize: 表示内核页的大小
- MMUPageSize: 表示内存管理页的大小
- RSS(Resident Set Size): 表示该虚拟区域里驻留在物理内存中的大小
- Pss(Proportional Set Size): 表示该区域里占用共享映射物理内存的大小
- Pss_Dirty: 表示该区域占用共享映射物理内存变成脏页的大小
- Anonymous: 表示虚拟区域里采用匿名映射的物理内存大小
- LazyFree: 表示虚拟区域里可以通过惰性释放的物理内存大小(无需写回到磁盘)
- Referenced: 表示虚拟区域里被访问物理内存的大小
- Locked: 表示虚拟区域里被 LOCK 的物理内存大小,以防止 SWAP OUT
- Shared_Clean: 表示虚拟区域里共享映射的干净物理内存大小
- Shared_Dirty: 表示虚拟区域里共享映射的脏页物理内存大小
- Private_Clean: 表示虚拟区域里私有映射干净物理内存大小
- Private_Dirty: 表示虚拟区域里私有映射脏页物理内存大小
- AnonHugePages: 表示虚拟区域里匿名映射的 THP 物理内存大小
- ShmemPmdMapped: 表示虚拟区域里 THP 共享内存大小
- FilePmdMapped: 表示虚拟区域里采用文件映射大页物理内存的大小
- Shared_Hugetlb: 表示虚拟区域里共享 Hugetlb 大页的大小
- Private_Hugetlb: 表示虚拟区域里独占 Hugetlb 大页的大小
- Swap: 表示虚拟区域里已经被 SWAP OUT 物理内存大小
- SwapPss: 表示虚拟内存区域里已经 SWAP OUT 物理内存占比
- Locked: 表示虚拟内存区域里被 LOCKED 住的物理内存大小
- THPeligible: 表示虚拟内存区域是否具备 THP 能力
- ProtectionKey: 表示虚拟内存区域具有的 ProtectionKey 信息
- VmFlags: 表示虚拟区域具有的属性
PROC SMAPS 机制的工作原理很简单,首先从打开的文件找到对应的 struct inode, 然后找到对应进程的 struct mm_struct, 因为进程可以读自己的 SMAPS 文件,也可以读其他进程的 SMAPS 文件,因此第一步的目的就是找到目标进程的 struct mm_struct. 接下来会遍历进程里所有的 VMA 区域,每当遍历一个 VMA 区域时,会调用 PageWalk 机制遍历区域内的所有页表,并收集页表的信息和映射物理内存对应的 struct page 信息等. 最后将收集到的信息进行输出,一般情况下基于 SEQ_FILE 输出到用户空间.
File-Mapping and Anonymous-Mapping
在 Linux 用户空间,虚拟内存可以通过两种映射方式与物理内存建立映射关系,第一种是 File-Mapping 文件映射,其可以将文件内容映射到用户空间,虚拟内存和磁盘文件中间通过 Page CACHE 进行数据中转,因此可以像普通虚拟内存一样访问文件; 另外一种是 Anonymous-Mapping 匿名映射, 用于将用户空间虚拟内存映射到物理内存上,以满足进程对内存的需求,例如堆(Heap)内存、堆栈(Stack)内存、以及 MMAP 内存等。PROC SMAPS 机制可以统计某段虚拟内存区域里匿名映射内存的数量,并通过 Anonymous 字段进行显示:
PROC SMAPS 机制没有直接的统计文件映射对应物理内存的大小,而是只统计了 Anonymous 映射对应物理内存的大小,那么文件映射如何统计呢? 接下来通过多个实践案例进行讲解, 首先是 Anonymous 映射的案例,其在 BiscuitOS 上的部署逻辑如下: