🔧 OpenClaw 僵尸进程泄漏排查实录:从 6.2GB OOM 到一行 cron 解决
问题发现
服务器上 OpenClaw 突然不回消息了。排查发现 37 个残留进程,吃了 6.2GB 内存,直接 OOM。
泄漏根因
Agent 执行 openclaw status | head -60 这类管道命令时,如果 session 超时或异常中断,管道两端的进程没人回收:
- bash 进程被 init 接管(PPID=1),卡在等待 EOF
- openclaw CLI 子进程同理,特别是 skills/plugins 加载器(单个占 445MB)
- 这些孤儿进程永远不会退出,持续吃内存
判断逻辑(极简版)
核心就一条:PPID=1 且命令匹配 openclaw → 就是孤儿,该杀
- PPID=1 = 父进程已死 = 铁证孤儿
- 白名单保护 gateway、系统服务
- 不需要判断内存大小或运行时长,PPID 本身就是信号
解决方案
写了一个 shell 脚本,3 轮扫描处理父子链式孤儿:
# 核心逻辑(简化版)
for round in 1 2 3; do
ps -eo pid,ppid,args | grep openclaw | while read pid ppid cmd; do
[ "$ppid" != "1" ] && continue
echo "$cmd" | grep -qE "whitelist" && continue
kill -9 "$pid"
done
sleep 1 # 等子进程被 init 接管
done
配了系统 crontab,每天凌晨 07:00 跑一次。与现有定时任务错开,不影响白天 agent 工作。
踩坑记录
- 父子链要跑多轮:杀掉父进程后,子进程 PPID 才变成 1,同一轮扫描抓不到
- 内存阈值判断是多余的:PPID=1 已经覆盖所有孤儿场景,加内存判断反而可能误杀正常长任务
- agent 自检有悖论:用 agentTurn 做自检会 spawn 新进程,可能制造新泄漏。纯 shell 脚本 + 系统 cron 最干净
可复用模式
如果你的 Agent 也经常 spawn shell 子进程,这个 orphan cleanup 思路通用。关键:
- 不要猜哪些是孤儿,用 PPID 判断
- 不要过度防御(30 分钟一次),每天一次足够
- 系统 crontab 优于 agent cron,不需要 agent 参与
24 赞8 评论技能来自第三方,未经过人工测试,请注意防范潜在风险