본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 06. 17. 15:54

Claude Code가 RAM을 고갈시키는(커널 패닉을 일으키는) 원인은 토큰 비대화가 아닌 MCP 프로세스 누수 — 발견 방법, 안전한 회수

요약

Claude Code 사용 시 발생하는 메모리 고갈 및 커널 패닉의 원인이 토큰 비대화가 아닌, 종료된 세션에서 남겨진 MCP 서버 프로세스 누수임을 밝힙니다. PID 1로 재부모화된 고아 프로세스를 안전하게 식별하고 회수하는 방법과 예방책을 제시합니다.

핵심 포인트

  • 메모리 문제는 토큰 크기가 아닌 MCP 서버 프로세스 누수 때문임
  • 종료된 세션의 MCP 서버가 PID 1로 재부모화되어 RAM을 점유함
  • 특정 패턴을 이용해 PID 1의 프로세스 중 MCP 서버만 선별적 탐지 가능
  • 프로세스 회수 스크립트 활용 및 cgroup을 통한 메모리 상한 설정 권장

Claude Code를 사용하다 보면 메모리가 서서히 점유되어, 결국 머신이 스왑(swap) 때문에 기어가는 듯이 느려집니다. 심하면 멈추거나, 커널 패닉(kernel panic)이 발생하여 재부팅을 강요받기도 합니다. 이럴 때 흔히 보이는 "Claude Code가 RAM을 먹는다" 식의 대처(토큰이나 로그 정리)로는 해결되지 않습니다. 그것은 컨텍스트(context)의 크기에 관한 문제이며, 여기서 발생하는 것은 별개의 사고입니다.

정체는 세션이 종료되었음에도 살아남은 MCP 서버나 서브 에이전트(sub-agent)의 자식 프로세스가 쌓여서, RAM과 swap을 고갈시키는 것입니다.

이는 실제로 존재하며 반복적으로 보고되고 있는 사고입니다. 2026년 5월부터 6월 사이의 이슈 티켓만 해도, #64366(11개의 MCP 서버가 약 300개의 프로세스로 증가하여 swap 24GB 사용, 4일 동안 4번의 커널 패닉), #68647(병렬 서브 에이전트가 자식 프로세스를 누수시켜 128GB를 고갈시키고 macOS의 watchdog이 패닉), #66020, #68933, #61748(150개 이상의 프로세스, 31GB) 등 10건이 넘습니다. 동일한 형태가 Copilot CLI나 Codex에서도 보고되고 있으며, 이는 하나의 도구의 버그가 아니라 에이전트 시대의 구조적인 사고입니다.

Claude Code(나 서브 에이전트)가 MCP 서버를 기동하면, 해당 서버는 자식 프로세스가 됩니다. 세션이나 서브 에이전트가 종료될 때, 본래는 해당 서버도 정리되어야 합니다. 하지만 정리되지 않고 남는 경우가 있습니다. 남은 서버는 **PID 1로 재부모화(re-parented)**되어, 메모리를 점유한 채 계속 동작합니다. 며칠 동안 세션을 돌리다 보면, 죽은 세션의 MCP 서버가 수십 개씩 메모리를 다투게 되고, 결국 OOM killer(또는 패닉)로 끝납니다.

핵심은 "PID 1로 재부모화되어 있음"과 "MCP 서버다운 외형"이라는 두 가지 조건을 모두 만족하는 프로세스입니다. 재부모화되었다는 사실만으로는 아무 의미가 없습니다. 당신의 정당한 데몬(daemon)도 PID 1의 자식이기 때문입니다. 따라서 PID 1의 프로세스를 무분별하게 죽여서는 안 됩니다.

ps -eo pid,ppid,etimes,rss,args | awk '$2==1 && /@modelcontextprotocol|mcp-server-|[/ ]mcp[ _-]/ {printf "%s age=%ss %sMB %s\n",$1,$3,int($4/1024),$0}'

한 줄이 하나의 누수된 서버를 나타내며, PID, 동작 시간, 실제 메모리, 명령어가 출력됩니다. 이것이 여러 줄 나온다면, 그것이 바로 당신의 RAM을 갉아먹고 있는 주범입니다.

다음 스크립트는 누수 목록을 나열하며, MCP 서명(signature)과 일치하는 것만 대상으로 합니다. 기본값은 dry-run(무엇을 지울지 보여주기만 하고 아무것도 지우지 않음)입니다. --kill을 붙였을 때만 회수합니다.

#!/bin/bash
# mcp-orphan-reaper.sh — PID 1로 재부모화된 누수 MCP 서버를 목록화(기본값)/회수(--kill)
# MCP 서명과 일치하지 않는 프로세스에는 일절 손대지 않음
...

저는 이것을 WSL2 실기에서 확인했습니다. 가짜 MCP 서명이 붙은 고아 프로세스를 탐지하고, MCP 서명이 아닌 정당한 PID 1 데몬에는 손대지 않으면서 깔끔하게 회수합니다. 안전의 핵심은 서명의 일치이며, MCP 서버처럼 보이지 않는 프로세스에는 절대로 시그널을 보내지 않습니다.

회수는 사후 처리일 뿐입니다. 진짜 대책은 상한(ceiling)을 설정하는 것입니다. MCP를 많이 사용하는 무거운 세션을 메모리 상한 아래에서 실행해 두면, 폭주하는 누수가 발생하더라도 상한에 걸려 종료될 뿐 머신 전체를 길동무 삼지는 않습니다.

# systemd 호스트: 8GB에서 세션의 cgroup을 종료(스왑 사망이 아닌)
systemd-run --scope -p MemoryMax=8G claude
# 어떤 쉘에서든: 가상 메모리 상한(KB)을 세션과 자식에게 부과
...

상한은 실제 작업량보다는 높게, 총 RAM보다는 충분히 낮게 설정합니다. 이렇게 하면 누수가 발생해도 재부팅이 아닌, 단순한 번거로움 정도로 끝납니다.

가장 저렴한 방법은 다음 세션이 시작될 때 이미 누수가 쌓여 있는지 경고를 받는 것입니다. 이를 수행하는(경고만 하고 아무것도 죽이지 않으며, 서명으로 안전하게 선별하는) SessionStart 훅 mcp-orphan-leak-warner.sh를 무료 안전장치 모음인 cc-safe-setup에 포함했습니다. 위의 스크립트는 도입 없이 그대로 사용할 수 있습니다.

「Claude Code가 RAM을 점유한다」고 생각되면, 먼저 ps를 사용하여 PID 1의 MCP 서버가 쌓여 있지 않은지 확인하세요. 토큰을 정리하기 전에 그 부분을 먼저 확인하시기 바랍니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0