第 5 篇
OOM 与资源耗尽:系统是如何被"慢慢拖死"的 🧠🔥

在很多工程事故复盘中,OOM(Out Of Memory)并不是"第一现场"。
当系统最终 reset、watchdog 触发、服务集体失效时,OOM 往往已经发生在更早之前,只是没有被正确识别、记录或关联。
在车载 Linux 系统中,OOM 更像是一种系统层面的连锁反应触发器:
内存压力 → 关键线程异常 → 系统负载失控 → 监控失效 → reset
本篇将从工程视角出发,系统性回答三个核心问题:
- OOM 在车载系统中通常是如何"被触发"的?
- 哪些进程绝对不应该被 OOM kill?
- 一个 memory leak,最终是如何一步步演化成 reset 的?
一、先澄清一个误区:OOM ≠ 进程用光了内存
在很多团队中,OOM 仍然被简单理解为:
"某个进程内存用太多,被系统杀掉了。"
但在内核层面,OOM 是内存回收失败后的"最后手段"。
触发 OOM 的前提,通常是:
- 全局内存紧张(不仅仅是 RSS 增长)
- page reclaim 失败
- slab / page cache 无法回收
- cgroup / zone 内存耗尽
📌 工程结论:
OOM 并不是"某个进程坏了",而是系统已经没有退路了。
二、车载系统中 OOM 更容易发生的真实原因
相比服务器环境,车载 Linux 有几个天然"劣势":
1️⃣ 内存资源本身就有限
- SoC RAM 规模受成本严格限制
- 多功能域(感知 / 通信 / 日志 / OTA)共用内存
- 安全分区、保留内存不可回收
2️⃣ 内存碎片问题更严重
- 长时间运行
- DMA / CMA / ION 等特殊内存
- slab 对象无法合并
3️⃣ 中间件是"隐形大户"
在车载系统中,以下模块经常成为内存压力的放大器:
- SOME/IP / DDS 的 buffer queue
- 历史数据缓存
- 日志 ring buffer
- 网络重传 / backlog
它们单次分配不大,但持续累积。
三、OOM 在车载系统中通常不是"单点事故"
1️⃣ 典型的连锁反应路径
text
内存缓慢增长
↓
系统进入 reclaim
↓
分配延迟变大
↓
关键线程调度受阻
↓
系统 load 上升
↓
监控 / 喂狗线程被延迟
↓
watchdog reset
📌 注意:
在这个过程中,OOM kill 甚至可能还没发生。
2️⃣ 为什么很多现场"没看到 OOM log"
常见原因包括:
- OOM 发生后系统立即 reset
- journal 未持久化
- 内核 log buffer 太小
- 被 OOM kill 的是日志进程本身
因此:
"没看到 OOM" ≠ "没发生 OOM"。
四、哪些进程在车载系统中绝不能被 OOM kill ⚠️
这是一个架构级问题,而不是调参问题。
1️⃣ 典型"禁止被杀"的进程
- systemd / init
- watchdog / supervisor
- 网络管理(如 netmgr)
- 安全监控 / health monitor
- 日志守护进程(journal / logd)
如果这些进程被 kill,系统通常会:
- 立即 reset
- 或进入不可恢复状态
2️⃣ 工程手段(原则性)
- 使用 OOM score 调整
- 使用 cgroup 做内存隔离
- 明确"牺牲进程池"
📌 关键思想:
与其让内核"随机杀",不如工程上提前指定代价最低的牺牲者。
五、memory leak 是如何一步步拖死系统的
1️⃣ 第一阶段:表面一切正常
- RSS 稳定增长
- 功能不受影响
- 监控阈值未触发
2️⃣ 第二阶段:系统开始变"慢"
- 分配耗时增加
- 中间件 queue 堆积
- 周期任务 jitter 增大
3️⃣ 第三阶段:系统稳定性下降
- CPU load 升高
- RT 线程被打断
- 网络 / IPC 超时增多
4️⃣ 第四阶段:事故发生
- OOM kill 关键进程
- 或 watchdog reset
📌 重点:
reset 只是结果,memory leak 才是根因。
六、工程上如何"提前看到"OOM 的影子
1️⃣ 必须长期监控的指标
- MemAvailable
- Slab / SReclaimable
- Page fault 频率
- 中间件 buffer 深度
bash
cat /proc/meminfo
2️⃣ 日志与事件的关联
- 内存告警时间点
- load 上升时间点
- 网络异常时间点
- reset / WDT 时间点
只有把它们放在同一条时间线上,OOM 才会"现形"。
七、OOM 是系统问题,而不是内存问题
这是本篇最重要的一句话。
OOM 在车载系统中意味着:
- 架构上没有兜底
- 资源隔离不足
- 监控介入太晚
真正成熟的车载系统,应当做到:
- OOM 成为"可预期事件"
- reset 成为"最后兜底"
- 关键服务永远不会被 OOM kill
八、小结
- OOM 往往是连锁反应的一环
- memory leak 是典型"慢性致命伤"
- reset 只是系统给出的最终答案
在下一篇中,我们将进入一个更"底层"的领域:
当问题无法复现时,Trace 如何成为你唯一的"时间机器"?
(未完待续)