kswapd 在后台执行,提前回收内存以保持水位。此阶段对应用透明,不阻塞业务线程的内存申请。/proc/meminfo 估算):Active(file) + Inactive(file),是文件内容的内存缓存,与文件 I/O 性能直接相关。这部分内存可被内核回收。Cached 和 Shmem。Active(anon) + Inactive(anon),是进程私有匿名内存(如 malloc 分配的堆内存)。free 命令输出的 buff/cache 一列看似有大量可回收缓存(因为 Cached 统计包含了 Shmem),但其中绝大部分可能是匿名共享内存,内核实际可回收的 file-backed cache 已经少得可怜。free 或 /proc/meminfo 确认内存整体占用情况:free -hcat /proc/meminfo
MemTotal、MemFree、Cached、Shmem、Active(anon)、Inactive(anon)、Active(file)、Inactive(file) 等字段。/proc/meminfo 估算 page cache 的构成:Active(file) + Inactive(file)ShmemActive(anon) + Inactive(anon)Cached 数值很大,但 Active(file) + Inactive(file) 非常低,说明大部分 cache 是 Shmem(共享匿名内存),file-backed cache 已被大量回收。top 命令查看进程的 SHR 与 RSS,如果某进程 SHR 接近 RSS,可推断该进程大部分使用的是共享内存(如 mmap(MAP_ANON|MAP_SHARED) 方式申请的匿名共享内存)。Cached 和 Shmem,但在无 swap 设备时无法被回收。free 输出的 buff/cache 一列由 Cached + Buffers + Slab 计算得出,仅看该列数值会高估可回收内存量。/proc/vmstat 的 allocstall 计数判断是否发生同步回收:grep allocstall /proc/vmstat
allocstall 持续增加,说明系统正在频繁发生 direct reclaim,此时应用的内存申请会被阻塞。top 或 ps 观察 kswapd 内核线程的 CPU 使用率:top -p $(pgrep kswapd | tr '\\n' ',' | sed 's/,$//')
kswapd0、kswapd1 等线程 CPU 使用率持续偏高,说明系统内存紧张,异步回收已全速运转但仍然跟不上内存消耗,即将或已经进入 direct reclaim 阶段。iotop 观察磁盘 IO 来源:iotop -oPa
iotop 的两个指标数据来源不同:Actual DISK READ:从 /proc/vmstat 读取,表示块设备与硬件之间的实际读写带宽。Total DISK READ:从 /proc/<pid>/io 读取,表示线程对应的 IO。/proc/<pid>/io,但通常不同时记录在 /proc/vmstat。/proc/<pid>/io,但不会记录在 /proc/vmstat。/proc/<pid>/io 记录的是文件内容 IO,不记录文件系统元数据 IO(如删除文件时只涉及元数据变更,/proc/<pid>/io 变化很小,但 /proc/vmstat 会记录)。iotop 无法关联到具体 pid。mmap(MAP_ANON|MAP_SHARED) 等方式大量申请匿名共享内存,占用系统大部分内存。iotop 无法关联到具体进程。mmap(MAP_ANON|MAP_SHARED) 占用。swappiness 参数。对于延迟敏感型业务,swap 作为兜底手段而非常规回收途径更合适。free 命令判断可回收内存:free 的 buff/cache 列包含 Shmem,而匿名共享内存在无 swap 时不可回收。应结合 /proc/meminfo 的 Active(file) + Inactive(file) 判断实际可回收的 file-backed cache。iotop 中 Actual DISK READ > Total DISK READ 是正常现象:当 IO 由内核 routine 触发(如 pagefault 读盘)时,没有对应 pid,Actual 会大于 Total。这不是 iotop 的 bug,而是数据来源差异导致的。allocstall 计数是判断 direct reclaim 的关键指标:异常期间持续采样该计数,若持续增长即可确认同步回收正在发生。文档反馈