Skip to content

bug: MCP 子进程泄漏 — 每次会话结束未回收,累积占用数 GB 内存 #104

Description

@sundanian1991

问题描述

zcode-cli 每次启动新 AI 会话时会拉起一套 MCP 子进程(tavily-mcp / @getnote/mcp / @modelcontextprotocol/server-sequential-thinking),但会话结束后这些子进程不会被回收,持续堆积在后台,导致内存占用不断增长。

环境信息

  • ZCode 版本:3.3.1
  • 系统:macOS 15.5 (darwin 24.6.0 arm64)
  • 内存:32 GB
  • 开机时长:20 天(未重启)

复现步骤

  1. 正常使用 zcode-cli,进行多次 AI 会话(每次会话配置了 3 个 MCP server)
  2. 随着会话次数增加,内存占用持续上升
  3. 检查进程列表发现大量 npm exec 僵尸进程

实际现象

运行 20 天后,发现 286 个 npm exec 僵尸进程,占用 4.9 GB 内存:

=== npm exec MCP 实例统计 ===
96 个  @getnote/mcp
95 个  tavily-mcp
95 个  @modelcontextprotocol/server-sequential-thinking

=== 父进程分布 ===
283 个 → 父进程为 zcode-cli
3 个   → 父进程为 claude

每个 MCP server 被重复启动了 90+ 次,其中最老的进程已运行超过 1 天。会话结束后对应的子进程仍然存活。

期望行为

会话结束后,zcode-cli 应主动终止其拉起的 MCP 子进程,或实现进程复用(多个会话共享同一套 MCP 实例),避免重复启动。

影响

  • 内存泄漏:20 天累积 4.9 GB 被浪费
  • 系统卡顿:内存压力升高,触发频繁压缩/换页
  • 需要手动清理或定期重启才能缓解

临时缓解方案

手动清理脚本(保留最近 5 分钟的活跃进程):

ps -eo pid,etime,args | grep '[n]pm exec' | \
  grep -E 'tavily-mcp|@getnote/mcp|server-sequential-thinking' | \
  while read -r pid etime rest; do
    mins=$(echo "$etime" | awk -F'[-:]' '{
      if (NF==4) print $1*1440+$2*60+$3
      else if (NF==3) print $1*60+$2
      else print $1
    }')
    [ "${mins:-0}" -gt 5 ] && kill "$pid" 2>/dev/null
  done

清理后内存立即释放约 4.9 GB,空闲内存页从 6,319 恢复到 367,273。

建议

  1. 会话结束时清理子进程:在 zcode-cli 会话生命周期结束时,主动 kill 拉起的 MCP 进程
  2. 进程复用:多个会话共享同一套 MCP server 实例,避免重复启动
  3. 增加心跳检测:定期检查 MCP 子进程是否仍被需要,超时未使用的自动回收

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions