news 2026/10/7 15:05:22

Linux 内存回收机制:水位线、kswapd 与 Direct Reclaim

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 内存回收机制:水位线、kswapd 与 Direct Reclaim

Linux 内存回收机制:水位线、kswapd 与 Direct Reclaim

源码基线:Linux v6.18.9(mm/page_alloc.c/mm/vmscan.c)。

现象:内存明明还有(free数 GB),进程却偶发卡顿几百毫秒,P99 翻倍。
根因:kswapd 回收跟不上分配速度,水位跌破min后,业务线程被迫在分配路径上亲自回收(Direct Reclaim),并触发内核节流。

一、三条水位线:谁来收债

─────────────────── high ← kswapd 回收到这里就睡 ─────────────────── low ← 跌破这里唤醒 kswapd(后台收债,业务无感) ─────────────────── min ← 跌破这里,分配线程自己收债(Direct Reclaim,卡顿)
水位区间行为业务感知
高于 low快路径直接返回页框无
low ~ min唤醒 kswapd 后台回收基本无
低于 min当前线程进入慢路径亲自回收卡顿
grep-A5"Node 0"/proc/zoneinfo|grep-E"min|low|high"# 查看水位(单位:页)

二、Direct Reclaim 调用链(v6.18.9)

alloc_pages() └─ 快路径失败 → __alloc_pages_slowpath() # 先 wake_all_kswapds(), # 再按 ALLOC_WMARK_MIN 重试 └─ __alloc_pages_direct_reclaim() # psi_memstall_enter() └─ __perform_reclaim() └─ try_to_free_pages() # ← 业务线程开始收债 └─ do_try_to_free_pages() → shrink_zones() → shrink_node() (MGLRU 启用时走 lru_gen_shrink_node()) └─ 收到页返回(几十~几百 ms);收不到 → OOM

7.0 中shrink_zones()更名为shrink_one(),其余不变。

为什么慢——回收线程扫到不同页的代价:

页类型代价量级
干净 Page Cache直接丢微秒
脏页回写 I/O + 节流毫秒起
匿名页换出 swap/zram毫秒

三级节流(卡顿的真正来源):

  1. 撞见大量回写页 →reclaim_throttle(VMSCAN_THROTTLE_WRITEBACK),睡最长 100ms
  2. 回收连续无进展 →VMSCAN_THROTTLE_NOPROGRESS
  3. min 以下保护区耗尽 →throttle_direct_reclaim(),睡等 kswapd 救回水位

多线程同时分配会集体进 Direct Reclaim,形成"集体抖动"。

MGLRU(6.12 起默认)改变扫描方式,但水位线、触发条件、计数器全部不变,排查方法照用。

三、观测与实锤

grep-E"allocstall|pgscan_direct|pgscan_kswapd|pgsteal|throttle"/proc/vmstat
计数器含义信号
pgscan_kswapd后台扫描量稳定 = 正常
pgscan_direct前台扫描量持续增长 = 业务在收债
allocstall_*进 Direct Reclaim 次数增长 = 卡顿元凶
pgscan_direct_throttle睡等 kswapd 救援次数非零 = 最危险阶段
drsnoop-bpfcc# 专抓 Direct Reclaim 延迟cat/proc/pressure/memory# full avg10 高 = 撞见回写perfstat-e'vmscan:mm_vmscan_direct_reclaim_begin'-asleep10

典型卡顿栈:__alloc_pages_direct_reclaim → __perform_reclaim → try_to_free_pages → shrink_node → reclaim_throttle

四、缓解手段

手段作用点代价
调大vm.min_free_kbytes抬水位,给 kswapd 提前量常驻内存变少
调大vm.watermark_scale_factor更早唤醒 kswapd同上
降低vm.swappiness倾向回收文件页匿名页压力大时 OOM 更早
业务削峰 / 内存池避免集体进慢路径改业务
cgroup 限额压力隔离到容器限额内仍会发生
查磁盘与vm.dirty_*降低回写节流命中基础设施成本

排查顺序:pgscan_direct涨 → 确认 Direct Reclaim →pgscan_direct_throttle涨 → 抬水位+查 kswapd → 否则查 Dirty/Writeback 与磁盘 → 再查 swap/zram。

能做:隔一分钟跑一次grep -E "allocstall|pgscan_direct" /proc/vmstat,数字在涨,说明你的业务线程正在替内核收债。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 15:05:08

AI 练习项目 智能数仓问答

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 15:05:01

云数据中心特点

云数据中心特点:资源池化。通过虚拟化技术将计算,存储和网络资源统一整合,形成共享资源池,提高资源利用率。按需服务,根据业务需求动态分配和回收资源,实现资源的弹性供给。高可靠性,采用冗余设…

作者头像 李华
网站建设 2026/10/7 15:02:54

ponytail 插件实战:工作区代码整理与临时文件收束指南

第一次听说 ponytail 这个插件时,我下意识以为是个搞笑项目。一个做代码整理的编辑器插件,起名叫“马尾辫”,多少有点无厘头。但真在杂乱项目里用上之后,我反而觉得这名字起得相当贴切:散落各处的临时文件、随手写的调…

作者头像 李华
网站建设 2026/10/7 15:02:21

OpenClaw 2026.x Windows + WSL2 完整部署:从 Node.js 到 Ubuntu 环境一次跑通

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华