Linux中无法直接检测“内存溢出”,OOM是内核强制杀进程行为;预防性检测用MemAvailable占比与swap活动判断,事后确认查dmesg或/proc/sys/vm/oom_kill_allocating_task。

Linux 系统中没有“内存溢出”这一精确的运行时状态可被条件语句直接检测——OOM(Out of Memory)是内核在资源耗尽时触发的强制杀进程行为,不是用户态可轮询的布尔状态。所谓“检测是否溢出”,实际是指:在脚本中提前识别内存严重不足的风险趋势,或确认 OOM 是否已发生过。下面分两类场景给出高效、实用的判断方式。
一、判断当前内存是否濒临 OOM(预防性检测)
核心逻辑是监控 MemAvailable 占总内存比例,并结合交换使用情况。避免用 used 或 free 判断,它们会因 page cache 产生误报。
- 读取
/proc/meminfo中关键字段,计算可用内存占比:
```bash
# 单行判断:若可用内存低于总内存的 5%,返回真(需 root 或普通用户权限,/proc/meminfo 可读)
awk '/^MemTotal:/ {total=$2}/^MemAvailable:/ {avail=$2} END {exit (avail/total ```
- 同时检查 swap 使用量是否增长(
SwapUsed > 0且si/so持续非零):
```bash
# 检查是否有活跃 swap I/O(过去 1 秒内发生换入或换出)
vmstat 1 2 | tail -1 | awk '$6+$7 > 0 {exit 0} {exit 1}'
```
- 组合成 shell 条件语句示例:
```bash
if awk '/^MemTotal:/ {t=$2} /^MemAvailable:/ {a=$2} END {exit (a/t echo "⚠️ 内存紧张:可用内存不足 5%,且无 swap 活动,可能即将 OOM"
fi
```
二、判断 OOM 是否已经发生(事后确认)
内核在触发 OOM Killer 后会在日志中留下明确痕迹,这是唯一可靠的“已溢出”证据。
- 检查
dmesg输出中最近是否有 OOM Killer 记录:
```bash
# 查看最近 100 行内核日志中是否含 "Killed process"
dmesg -T | tail -100 | grep -q "Killed process" && echo "✅ 已触发 OOM Killer"
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 更严谨写法(排除时间戳格式差异,适配不同内核版本):
```bash
if dmesg | tail -50 | grep -q -E "(Out of memory|Killed process|oom-killer)"; then
echo "OOM 已发生"
fi
```
三、不推荐但常见误区:用 free 的 used 做条件判断
以下写法错误且危险:
```bash
# ❌ 错误:used 高 ≠ 内存危机;Linux 会主动缓存,used 高反而是健康表现
if [ $(free | awk 'NR==2{print $3}') -gt 1000000 ]; then ...
```
它把 used 当作“被程序占用”的内存,忽略了 buff/cache 的可回收性,极易导致误告警或漏判。
四、生产环境建议:用 CommitLimit 与 Committed_AS 做 overcommit 预警
当启用内存 overcommit(默认开启),真正决定是否 OOM 的是提交内存是否超限:
```bash
# 若已承诺内存 ≥ 95% 的承诺上限,则 OOM 风险极高
awk '/^CommitLimit:/ {limit=$2} /^Committed_AS:/ {comm=$2} END {exit (comm/limit > 0.95) ? 0 : 1}' /proc/meminfo
```

















