首页 教程 分类 Skills下载 关于
ZH EN JA KO
故障排查

OpenClaw内存占用过高问题解决方法

· 14 分钟

前言

OpenClaw 基于 Node.js 运行,默认情况下 V8 引擎的堆内存上限约为 1.5GB(64位系统)。当你发现 OpenClaw 进程内存持续增长,甚至导致系统卡顿或 OOM(Out of Memory)被杀时,本文的排查方法将帮助你找到原因并解决问题。

一、快速判断内存状态

1.1 查看当前内存使用

# 方法一:通过 OpenClaw 健康端点
curl -s http://localhost:18789/health/detail | jq '.memory'

# 返回示例:
# {
#   "heapUsed": "185MB",
#   "heapTotal": "256MB",
#   "rss": "310MB",
#   "external": "12MB"
# }

# 方法二:直接查看进程内存
ps aux | grep openclaw | grep -v grep

# 方法三:使用 top/htop 实时查看
top -p $(pgrep -f "openclaw up")

1.2 内存指标含义

指标 含义 正常范围
RSS 实际物理内存占用 < 500MB
Heap Used V8 堆已使用量 < 300MB
Heap Total V8 堆总分配量 < 512MB
External C++ 对象内存 < 50MB

如果 Heap Used 持续增长且不回落,很可能存在内存泄漏。

二、Node.js 内存限制配置

2.1 设置最大堆内存

# 方法一:通过环境变量设置
export NODE_OPTIONS="--max-old-space-size=512"
openclaw restart

# 方法二:在配置文件中设置(PM2 方式)
# ecosystem.config.js
{
  env: {
    NODE_OPTIONS: "--max-old-space-size=512"
  }
}

# 方法三:Systemd 方式
# /etc/systemd/system/openclaw.service
# Environment=NODE_OPTIONS=--max-old-space-size=512

推荐的内存限制设置:

服务器内存 建议 max-old-space-size 说明
512MB 256 低配 VPS,需精简配置
1GB 384 入门级,支持 2-3 个频道
2GB 512 标准配置
4GB+ 1024 充足,适合多频道高并发

2.2 启用垃圾回收优化

# 暴露 GC,允许手动触发
export NODE_OPTIONS="--max-old-space-size=512 --expose-gc"

# 更积极的 GC 策略(降低内存但略影响性能)
export NODE_OPTIONS="--max-old-space-size=512 --gc-interval=100"

三、对话历史清理

对话历史是内存增长的主要原因之一。每个活跃对话都会在内存中保留上下文。

3.1 配置对话上下文限制

// ~/.config/openclaw/openclaw.json5
{
  "conversation": {
    // 每个对话保留的最大消息数
    "maxMessages": 50,
    // 对话空闲超时(秒),超时后清理内存
    "idleTimeout": 1800,
    // 最大并发对话数
    "maxConcurrent": 100,
    // 上下文窗口策略:sliding(滑动窗口) 或 summarize(摘要)
    "contextStrategy": "sliding"
  }
}

3.2 手动清理对话缓存

# 通过 API 清理所有非活跃对话
curl -X POST http://localhost:18789/admin/cleanup \
  -H "Content-Type: application/json" \
  -d '{"type": "conversations", "olderThan": "1h"}'

# 重启服务(会清空所有内存中的对话)
openclaw restart

3.3 定期自动清理

# 创建定时清理脚本
cat > /usr/local/bin/openclaw-cleanup.sh << 'EOF'
#!/bin/bash
curl -sf -X POST http://localhost:18789/admin/cleanup \
  -H "Content-Type: application/json" \
  -d '{"type": "conversations", "olderThan": "2h"}'
echo "[$(date)] 对话缓存清理完成" >> /var/log/openclaw-cleanup.log
EOF

chmod +x /usr/local/bin/openclaw-cleanup.sh

# 每小时执行一次
echo "0 * * * * /usr/local/bin/openclaw-cleanup.sh" | crontab -

四、内存泄漏检测

4.1 使用 Node.js 内置诊断

# 启动时开启堆快照功能
export NODE_OPTIONS="--max-old-space-size=512 --heapsnapshot-signal=SIGUSR2"
openclaw restart

# 在内存增长时生成堆快照
kill -USR2 $(pgrep -f "openclaw up")

# 快照文件会生成在工作目录,可用 Chrome DevTools 分析
# 打开 Chrome -> F12 -> Memory -> Load 快照文件

4.2 监控内存增长趋势

#!/bin/bash
# 保存为 memory-monitor.sh
# 每分钟记录一次内存使用,用于分析趋势

LOG_FILE="/var/log/openclaw-memory.csv"

# 写入表头
if [ ! -f "$LOG_FILE" ]; then
    echo "timestamp,rss_kb,heap_used,heap_total" > "$LOG_FILE"
fi

while true; do
    TIMESTAMP=$(date +%Y-%m-%dT%H:%M:%S)
    RSS=$(ps -o rss= -p $(pgrep -f "openclaw up") 2>/dev/null)
    HEALTH=$(curl -sf http://localhost:18789/health/detail 2>/dev/null)

    if [ -n "$RSS" ] && [ -n "$HEALTH" ]; then
        HEAP_USED=$(echo "$HEALTH" | jq -r '.memory.heapUsed')
        HEAP_TOTAL=$(echo "$HEALTH" | jq -r '.memory.heapTotal')
        echo "$TIMESTAMP,$RSS,$HEAP_USED,$HEAP_TOTAL" >> "$LOG_FILE"
    fi

    sleep 60
done

4.3 识别内存泄漏的特征

通过分析上述日志,判断是否存在内存泄漏:

  • 正常行为:内存在 GC 后能回到稳定水位,呈锯齿状波动
  • 内存泄漏:内存持续上升,GC 后的基线也在不断升高
  • 一次性增长:加载大量技能或连接多个频道时一次性增长,之后稳定

五、堆快照分析

5.1 生成堆快照

# 方法一:通过信号触发
kill -USR2 $(pgrep -f "openclaw up")
# 快照文件生成在当前工作目录

# 方法二:使用 v8-profiler(需要代码层面支持)
# 一般在开发调试时使用

5.2 使用 Chrome DevTools 分析

  1. 打开 Chrome 浏览器
  2. 地址栏输入 chrome://inspect
  3. 点击 "Open dedicated DevTools for Node"
  4. 切换到 Memory 标签页
  5. 加载 .heapsnapshot 文件
  6. 按 "Retained Size" 排序,找到占用最多内存的对象

5.3 常见内存泄漏源

泄漏源 表现 解决方法
未清理的事件监听器 EventEmitter 对象增长 确保 removeListener
全局缓存无上限 Map/Object 持续增长 设置缓存上限和 LRU 策略
未关闭的 WebSocket Socket 对象累积 检查断连清理逻辑
大型对话上下文 String 对象占用大 限制上下文长度
技能插件泄漏 第三方代码问题 逐个禁用排查

六、低内存设备优化

如果你在树莓派、低配 VPS 等内存受限的设备上运行 OpenClaw,以下配置可以显著降低内存使用。

6.1 精简配置

// ~/.config/openclaw/openclaw.json5 - 低内存优化版
{
  "conversation": {
    "maxMessages": 20,
    "idleTimeout": 600,
    "maxConcurrent": 20,
    "contextStrategy": "sliding"
  },
  "skills": {
    // 只加载必要的技能
    "autoLoad": false,
    "whitelist": ["basic-chat"]
  },
  "channels": {
    // 只启用必要的频道
  },
  "cache": {
    "maxSize": "50MB"
  }
}

6.2 使用 Swap 作为缓冲

# 创建 1GB swap 文件
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# 永久生效
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# 调整 swappiness(降低为10,优先使用物理内存)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

6.3 使用轻量模型

选择较小的模型可以减少上下文处理的内存开销:

{
  "models": {
    "primary": {
      "provider": "ollama",
      "model": "phi3:mini"  // 约 2GB 显存/内存
    }
  }
}

七、PM2 内存限制自动重启

利用 PM2 的内存限制功能,在内存超标时自动重启:

// ecosystem.config.js
module.exports = {
  apps: [{
    name: "openclaw",
    script: "openclaw",
    args: "up",
    max_memory_restart: "400M",
    env: {
      NODE_OPTIONS: "--max-old-space-size=512"
    }
  }]
};
# 应用配置
pm2 start ecosystem.config.js

# 查看内存使用和重启次数
pm2 describe openclaw | grep -E "memory|restart"

八、内存问题排查流程图

内存过高
  │
  ├── RSS > 500MB?
  │     ├── 是 → 检查 Heap Used
  │     │     ├── Heap Used 持续增长 → 内存泄漏
  │     │     │     ├── 生成堆快照分析
  │     │     │     ├── 逐个禁用技能排查
  │     │     │     └── 检查对话上下文限制
  │     │     └── Heap Used 稳定 → External 内存
  │     │           └── 检查 MCP Server 或原生模块
  │     └── 否 → 属于正常范围
  │
  └── 被 OOM Killer 杀死?
        ├── 增加 swap 空间
        ├── 设置 --max-old-space-size
        ├── 减少并发对话数
        └── 升级服务器内存

通过以上方法,你应该能够诊断并解决大多数 OpenClaw 内存相关的问题。如果内存泄漏持续存在,建议在 OpenClaw 的 GitHub 仓库提交 Issue,附上堆快照分析结果。

OpenClaw 是开源免费的个人AI助手,支持 WhatsApp、Telegram、Discord 等多平台接入