【Bug已解决】Memory leak / High memory usage / Process killed — Claude Code 内存泄漏解决方案

1. 问题描述

长时间运行 Claude Code 后,系统内存占用持续增长,最终进程被系统杀死:

# macOS 活动监视器显示 claude 进程占用 2GB+ 内存
$ ps aux | grep claude | grep -v grep
user  12345  95.0  45.2  2500234  2045678  ??  S    10:00AM   2:30.34 claude

# 或终端报 OOM 错误
<--- Last few GCs --->
[12345:0x12345678]    123456 ms: Mark-sweep 2048.5 (2123.2) MB, 456.3 / 0.0 ms
[12345:0x12345678]    123789 ms: Mark-sweep 2049.0 (2124.0) MB, 789.1 / 0.0 ms

<--- JS stacktrace --->
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

这个问题在以下场景中特别常见:

  • 长时间运行 Claude Code(数小时不退出)
  • 大型项目的上下文持续增长
  • MCP Server 内存泄漏
  • 大量会话历史积累
  • 频繁执行 /compact 但内存不释放
  • Node.js 默认堆内存限制(约 1.5GB)

2. 原因分析

核心原理拆解

Claude Code 运行 → 对话历史/MCP/缓存持续积累
        ↓
Node.js V8 堆内存持续增长
        ↓
达到 V8 堆内存上限(约 1.5GB)
        ↓
OOM: JavaScript heap out of memory

原因分类表

原因分类 具体表现 占比
对话历史积累 上下文和会话数据不释放 约 35%
MCP Server 泄漏 MCP 子进程内存泄漏 约 25%
日志/缓存积累 内存中缓存大量数据 约 20%
V8 堆限制 默认 1.5GB 不够 约 10%
/compact 无效 压缩后内存未释放 约 10%

3. 解决方案

方案一:增加 Node.js 堆内存(最推荐)

# 步骤 1:增加 V8 堆内存限制
export NODE_OPTIONS="--max-old-space-size=4096"
# 将堆内存限制提高到 4GB

# 步骤 2:永久设置
echo 'export NODE_OPTIONS="--max-old-space-size=4096"' >> ~/.zshrc
source ~/.zshrc

# 步骤 3:启动 Claude Code
claude

# 步骤 4:验证内存设置
node -e "console.log(v8.getHeapStatistics().heap_size_limit / 1024 / 1024 + ' MB')"

方案二:定期重启 Claude Code

# 步骤 1:每 2-3 小时退出并重新启动
/exit
claude --continue  # 恢复会话

# 步骤 2:或在长时间使用后
/compact
/exit
claude --continue

# 步骤 3:设置提醒
# 在终端中设置 alias 提醒
echo 'alias claude-timer="echo 开始计时; sleep 7200 && echo 该重启 Claude Code 了!"' >> ~/.zshrc

方案三:使用 /clear 定期清理

# 步骤 1:每 30-60 分钟使用 /compact
/compact
# 压缩上下文,释放部分内存

# 步骤 2:每 2 小时使用 /clear
/clear
# 完全清空上下文,释放大量内存

# 步骤 3:将关键信息保存到文件后再 /clear
> 将重要的架构决策保存到 docs/decisions.md
/clear
> 参考 docs/decisions.md 继续

方案四:减少 MCP 工具数量

# 步骤 1:检查 MCP 服务器
claude mcp list

# 步骤 2:移除不必要的 MCP 服务器
claude mcp remove <server_name>

# 步骤 3:MCP Server 是子进程,每个都消耗内存
# 减少 MCP Server 数量可以显著降低内存使用

# 步骤 4:定期重启 MCP
/mcp restart

方案五:清理会话历史

# 步骤 1:检查会话目录大小
du -sh ~/.claude/sessions/

# 步骤 2:清理旧会话
find ~/.claude/sessions/ -type f -mtime +7 -delete

# 步骤 3:清理日志
find ~/.claude/logs/ -type f -mtime +3 -delete

# 步骤 4:验证内存释放
ps aux | grep claude | grep -v grep

方案六:Docker 中限制内存

# 步骤 1:Docker 运行时设置内存限制
docker run --memory=4g --memory-swap=4g \
  -e NODE_OPTIONS="--max-old-space-size=3072" \
  node:22 claude

# 步骤 2:如果 OOM 被 Docker 杀死
# 增加内存限制
docker run --memory=8g \
  -e NODE_OPTIONS="--max-old-space-size=6144" \
  node:22 claude

4. 各方案对比总结

方案 适用场景 推荐指数 难度
方案一:增加堆内存 OOM 崩溃 ⭐⭐⭐⭐⭐
方案二:定期重启 长时间使用 ⭐⭐⭐⭐⭐
方案三:/clear 清理 内存增长 ⭐⭐⭐⭐⭐
方案四:减少 MCP MCP 泄漏 ⭐⭐⭐⭐
方案五:清理历史 磁盘+内存 ⭐⭐⭐⭐
方案六:Docker 限制 Docker 环境 ⭐⭐⭐⭐

5. 常见问题 FAQ

5.1 Node.js 默认堆内存是多少

Node.js 默认 V8 堆内存限制约为 1.5GB(64 位系统)。可以通过 --max-old-space-size 调整。

5.2 增加堆内存到多少合适

  • 4GB:适合大部分场景
  • 8GB:大型项目长时间运行
  • 不要超过系统物理内存的 70%

5.3 /compact 后内存为什么不释放

/compact 压缩了对话历史的逻辑大小,但 V8 的垃圾回收可能没有立即释放物理内存。完全释放需要 /clear 或重启进程。

5.4 MCP Server 内存泄漏如何检测

# 查看 MCP 子进程内存
ps aux | grep mcp | grep -v grep

# 如果 MCP 进程内存持续增长
# 重启 MCP Server
/mcp restart

5.5 Docker 中 claude 被 OOM-kill

Docker 的内存限制低于 Node.js 堆内存设置。确保 --memory 大于 --max-old-space-size

docker run --memory=4g -e NODE_OPTIONS="--max-old-space-size=3072" ...

5.6 如何监控 Claude Code 内存使用

# 实时监控
top -pid $(pgrep -f "claude" | head -1)

# 或
ps aux | grep claude | grep -v grep | awk '{print $6/1024 " MB"}'

5.7 长时间运行的最佳实践

  1. 每 30 分钟 /compact
  2. 每 2 小时 /clear(保存关键信息后)
  3. 每 4 小时退出并 claude --continue 重启
  4. 设置 NODE_OPTIONS=--max-old-space-size=4096

5.8 CI/CD 中的内存问题

CI 环境内存有限。使用 --print 模式避免交互式会话积累:

NODE_OPTIONS="--max-old-space-size=2048" claude --print "analyze code" --max-turns 10

5.9 macOS 上 claude 进程占用 2GB+

macOS 上 Node.js 进程内存包含 V8 堆 + C++ 层 + 缓冲区。实际 V8 堆可能只有 1GB,但总进程内存更高。增加 --max-old-space-size 并定期重启。

5.10 排查清单速查表

□ 1. 设置 NODE_OPTIONS=--max-old-space-size=4096
□ 2. 每 30 分钟 /compact 压缩上下文
□ 3. 每 2 小时 /clear 释放内存
□ 4. 每 4 小时退出并 claude --continue 重启
□ 5. 检查 MCP 子进程内存: ps aux | grep mcp
□ 6. 减少 MCP Server 数量
□ 7. 清理旧会话和日志文件
□ 8. Docker: --memory 大于 max-old-space-size
□ 9. CI/CD 使用 --print 和 --max-turns
□ 10. top 或 ps aux 监控内存使用

6. 总结

  1. 根本原因:内存泄漏最常见原因是对话历史持续积累(35%)和 MCP Server 内存泄漏(25%),Node.js 默认 1.5GB 堆内存不够
  2. 最佳实践:设置 NODE_OPTIONS=--max-old-space-size=4096 将 V8 堆内存提高到 4GB,并每 2 小时 /clear 释放内存
  3. 定期重启:长时间运行时每 4 小时退出并 claude --continue 重启进程,让操作系统完全回收内存
  4. MCP 管理:每个 MCP Server 是独立的子进程,减少不必要的 MCP Server 并定期 /mcp restart 回收内存
  5. 最佳实践建议:将关键上下文写入文件后定期 /clear,这比 /compact 更有效地释放内存——/compact 压缩逻辑大小但不保证物理内存立即释放

故障排查流程图

flowchart TD
    A[内存泄漏/OOM] --> B[设置 NODE_OPTIONS=4096]
    B --> C[重启 Claude Code]
    C --> D{OOM 消失?}
    D -->|是| E[✅ 问题解决]
    D -->|否| F[检查 MCP 内存]
    F --> G{MCP 内存高?}
    G -->|是| H[/mcp restart]
    G -->|否| I[/clear 清空上下文]
    H --> J{内存释放?}
    I --> J
    J -->|是| E
    J -->|否| K[退出并重启 claude]
    K --> L[claude --continue 恢复]
    L --> M{内存稳定?}
    M -->|是| E
    M -->|否| N[减少 MCP Server 数量]
    N --> O[清理会话和日志]
    O --> P[设置定期重启计划]
    P --> E
Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐