Claude Code 的資源黑洞: 從 11.3MB 單檔打包到 1.2TB 磁碟吞噬
Claude Code 的客戶端是一個沒有資源生命週期管理的 Node.js 單檔應用:啟動時解析 11.3MB 的打包檔案,執行時無限制地寫入磁碟,關閉終端後程序仍持續存活並持續消耗記憶體,直到系統崩潰。基於 GitHub Issues 中的真實使用者報告和社群逆向分析,本文系統梳理其在記憶體、CPU、磁碟三個維度上的資源管理缺陷,揭示打包架構、儲存設計和程序生命週期管理中的結構性問題。這些不是邊緣 case,而是從 2025 年 8 月到 2026 年 4 月持續被社群報告,卻被 stale 機器人批量關閉的系統性架構缺陷。
打包架構: 11.3MB 單檔的代價
Claude Code 的核心是一個名為 cli.js 的單檔打包產物,體積約 11.3MB。社群使用者 paultendo 在 Issue #29481 中對其進行了詳盡的靜態分析,揭示了多個嚴重的架構問題。
V8 啟動耗時: 32% 時間用於解析
CPU profiling 顯示 compileSourceTextModule 消耗了啟動階段 31.7% 的取樣時間。V8 引擎需要約 300ms 來解析這個 11.3MB 的單檔,而一個裸 Node.js 腳本的解析時間僅需 23ms。額外的 7.3% 消耗在 spawnSync 呼叫上,3.5% 消耗在垃圾回收上。這意味著在使用者輸入任何指令之前,已經有超過 40% 的啟動時間被浪費在純粹的解析開銷上。
全量載入: 只有 20 個動態 import
整個打包檔案在啟動時被完整解析和執行,僅有 20 個 import() 表達式。每個使用者都為所有功能付出了代價,無論是否使用。以下是本應按需載入卻被全量打包的元件:
pie title 打包檔案組成 (約 13.5MB)
"應用核心邏輯" : 7540
"AWS Bedrock SDK" : 1100
"highlight.js (182 種語言)" : 1000
"OpenTelemetry" : 900
"Google Vertex + gRPC + Protobuf" : 800
"RxJS" : 300
"其他 (Ink, Zod, Ajv, Axios 等)" : 1807一個編碼助手需要高亮 Brainfuck、MIPS assembly、Flix、Zephir、Inform7、Lasso 等 182 種語言,這本身就說明了打包策略的粗放程度。僅保留約 40 種常用語言就能節省約 786KB 的解析開銷。
依賴冗餘: 四個 HTTP 客戶端,三個驗證庫
不同 SDK 各自引入了獨立的依賴,導致打包檔案中同時存在四個 HTTP 客戶端 (Axios、Undici、Got、原生 fetch) 和三個驗證庫 (Zod、Ajv、JSON Schema)。在 Node 18+ 環境中,原生 fetch 已經完全可用,根本不需要額外的 HTTP 客戶端。
413 個同步檔案系統呼叫
打包檔案中包含 196 個 existsSync、109 個 statSync、108 個 readFileSync、58 個 mkdirSync 等,總計 413 個同步檔案系統呼叫。每一個都會阻塞事件迴圈。許多呼叫遵循 existsSync(path) && readFileSync(path) 的模式,兩個系統呼叫本可以用一個 try { await readFile(path) } catch {} 取代。
1087 個 CJS/ESM 互操作包裝器
每個被打包進 ESM 的 CommonJS 模組都生成了 __toESM/__commonJS/__require 相容性墊片,總計 1087 個。這些墊片既增加了解析重量,又帶來了每個模組的微小執行時開銷。
不必要的 Node 20 polyfill
打包檔案中包含 62 個 Promise 墊片(Node 0.12 起原生支援),57 個 Symbol 墊片(Node 4 起原生支援),57 個 async 轉換輔助函式(Node 8 起原生支援),以及 3 個 AbortController polyfill(Node 15 起原生支援)。這些來自為舊版 Node 或瀏覽器環境編譯的傳遞依賴,在目標執行時完全多餘。
ripgrep 打包全部 6 個平台二進位: 61MB
ripgrep 的 6 個平台二進位全部被打包,總計 61MB。與之對比,sharp 正確使用了 optional dependencies,僅安裝當前平台的二進位。這意味著每次安裝都浪費了約 51MB 的磁碟空間。
Ink 渲染性能隨對話長度退化
終端 UI 使用 Ink(React for Terminal)。分析顯示元件樹中有 6457 個 createElement 呼叫,578 個 useState hooks,但僅有 11 個 React.memo() 包裝器,比例僅 1.9%。在 Ink 中,每次狀態更新都會觸發完整的虛擬 DOM 協調。串流回應期間,每個到達的 token 都觸發狀態更新,導致未 memo 化的元件不必要地重新渲染。隨著對話增長,渲染輸出增長,每次重新渲染需要 diff 更多終端內容。這與 Issue #22265 中報告的「會話進行中越來越慢」現象一致。
磁碟吞噬: 從 GB 到 TB 的無限制增長
磁碟問題是 Claude Code 最嚴重的資源管理缺陷,影響範圍最廣,後果最嚴重。
Windows .node 原生模組泄漏: 每週 20GB
Issue #23095 記錄了一個持續數月未修復的問題:Claude Code 的 Windows 原生二進位檔案 (claude.exe) 在每次會話時向系統暫存目錄提取原生 Node.js 插件檔案,但從不清理。每個檔案約 6.6MB,使用者 SlothKing16 在 4 天內累積了 2813 個檔案,共 18GB。使用者 kolkov 的統計更為驚人:約 20GB/週,重度使用者可達 100GB/週。這個問題從 2025 年初被報告至今,期間被機器人多次標記為重複並嘗試關閉。
~/.claude 目錄: 3GB+ 無管理
使用者 kolkov 在 Issue #5024 中對一台日常使用 8 個月的機器進行了稽核:
pie title ~/.claude 目錄佔用 (約 3.1GB)
"projects/ (會話記錄)" : 2500
"debug/ (除錯日誌)" : 303
"file-history/ (檔案快照)" : 232
"history.jsonl (全域歷史)" : 10
"其他" : 55關鍵數字:最大單個會話 JSONL 檔案 203MB,最大子代理 JSONL 檔案 72MB,history.jsonl 包含 37000+ 條目。所有資料沒有輪轉,沒有壓縮,沒有清理機制。file-history/ 中的檔案快照沒有去重,同一檔案編輯 10 次就存儲 10 份完整副本。debug/ 目錄中的除錯日誌從不清理。
後台任務輸出檔案: 1.2TB 的自我引用死迴圈
Issue #32282 揭示了一個令人難以置信的設計缺陷。當 Claude Code 啟動多個後台代理並自動執行一個檢查進度的 bash 命令時,該命令的輸出檔案被寫入與被 glob 匹配的同一目錄,形成自我引用的無限回饋迴圈:
flowchart LR
A["bash: for f in tasks/*.output; tail -5 $f"] --> B["輸出寫入 tasks/task-A.output"]
B --> C["glob 匹配到 task-A.output 本身"]
C --> D["tail -5 讀取自身輸出"]
D --> E["追加寫入自身"]
E --> C多位使用者報告了相同的問題:1.2TB、460GB、303GB、235GB、480GB、36GB。該 issue 的評論者統計了 70 個相關的 open issues,分為 15 組,僅前兩組報告的磁碟消耗就達約 9.5TB。寫入速率可達 425MB/s,持續 18 分鐘,直到磁碟耗盡。
級聯故障: 磁碟滿後的不可逆崩潰
Issue #24207 描述了當磁碟被填滿後的災難性連鎖反應:
flowchart TD
A["磁碟空間 = 0"] --> B["寫入 .claude.json 失敗"]
B --> C["產生零長度檔案"]
C --> D["讀取為無效 JSON"]
D --> E["覆寫所有專案設定"]
E --> F["OAuth/API 令牌損壞"]
F --> G["需要重新認證"]
G --> H["所有執行中的代理/會話停止"]
H --> I["即使釋放磁碟空間也無法復原"]沒有預警,沒有優雅降級,沒有復原路徑。使用者必須手動終止所有程序,手動釋放空間,手動恢復設定,重新認證,重新配置所有設定。
同時寫入: 沒有鎖,沒有交易,沒有協調
~/.claude/ 目錄中唯一的鎖檔案是 .update.lock(5 位元組)。其他所有檔案寫入都沒有保護。當多個 Claude Code 程序同時執行時(代理 + 子代理是正常使用情境),它們對共享檔案的寫入沒有任何協調:
| 檔案 | 寫入者 | 鎖機制 | 已知後果 |
|---|---|---|---|
sessions-index.json | 專案中每個會話 | 無 | 競爭條件 |
{uuid}.jsonl | 主會話 + 壓縮 | 無 | 條目遺失 |
.claude.json | 每個程序 | 無 | 設定損壞(報告 8 次) |
file-history/* | 每次 Edit/Write | 無 | 無限增長 |
Windows 上情況更糟:原子寫入的變通方案(先寫 .tmp 再 rename())在 Windows 上失敗,因為當目標檔案被其他程序持有時 rename() 會回傳 EPERM,完全破壞了原子性。
記憶體與 CPU: 從 13GB RSS 到核心恐慌
Windows 極端記憶體消耗
Issue #24840 記錄了 Windows 上的極端案例:RSS 13.21GB,虛擬記憶體提交 47.17GB,而機器總記憶體僅 42.56GB。頁面錯誤 375 萬次,顯示持續進行磁碟 I/O。執行時間 347 秒中,使用者態 CPU 時間僅 35 秒,約 90% 的時間花在等待 I/O 和 swap 上。這導致其他應用(如 Opera 瀏覽器)完全無法回應。
macOS 核心恐慌
Issue #39253 報告了更嚴重的後果:在 MacBook Pro M3 Pro(18GB RAM)上,執行多個 Claude Code 實例會導致 macOS 核心恐慌。觀察到兩種不同的恐慌類型:Jetsam OOM kill(記憶體壓力導致 macOS 殺死關鍵的 watchdogd 程序)和 watchdog timeout(watchdogd 因系統資源飢餓 90+ 秒未簽到)。系統在沒有警告的情況下直接重啟,沒有錯誤對話框,沒有保存工作的機會。
程序孤兒: 關閉終端後仍持續存活
Issue #44507(2026 年 4 月,剛在幾天前)報告了一個基本的生命週期管理缺陷:關閉終端視窗後,Claude Code 程序仍持續存活。一個孤立的程序在 21 天內消耗了 35.4GB RSS,CPU 佔用 95.5%。根因是主 CLI 入口點沒有 process.stdin.on("end") 處理器,而 55+ 個 setInterval 計時器(設定輪詢、遙測、狀態欄刷新等)保持 Node.js 事件迴圈無限存活。V8 堆不受限制地增長,沒有空閒 GC 壓力,沒有 --max-old-space-size 限制,沒有自動終止看門狗。
100% CPU 凍結
Issue #27415 報告了 TaskStop 觸發的 100% CPU 凍結,根因是 Bun 執行時中 posix_spawn 的失控迴圈。Issue #26224 報告了 Claude Code 在處理大量提示時掛起 5-20 分鐘的問題。
扁平檔案架構的系統性失敗
分配而不清理: 貫穿所有 issue 的架構模式
社群成員 kolkov 在多個 issue 中反覆指出,所有這些問題的根本原因相同:
這個
.node泄漏不是一個孤立的 bug —— 它是一種反覆出現的架構模式的症狀,即 Claude Code 分配資源而不清理。
從 2025 年到 2026 年,問題從 .claude.json 單檔膨脹演變為 JSONL 檔案分散膨脹,但根本架構沒有改變:扁平檔案,沒有鎖,沒有交易,沒有清理,沒有壓縮。
SQLite 與本地守護程序: 社群的替代方案
社群多次提出使用 SQLite 替代扁平檔案儲存的建議。一個 SQLite 資料庫可以同時解決所有問題:WAL 模式提供並發讀取 + 單寫入的原子性,交易保證會話寫入的全有或全無,內建壓縮,TTL 清理,內容去重,跨平台一致性。
另一個建議是引入本地守護程序(類似 LSP 伺服器,Docker 的架構),所有 Claude Code 程序透過 IPC 通訊,提供協調而不改變儲存後端。
社群逆向工程與 stale 機器人的對比
社群成員 gebeer 的評論精準地概括了現狀:
感謝你的詳盡分析。這本該由維護者很久以前就完成的。
kolkov 進一步指出:
諷刺的是,社群實際上在替他們做除錯 —— 逆向工程混淆程式碼,追蹤錯誤路徑,提出帶程式碼片段的修復方案 —— 而回應是一個 60 天後關閉所有內容的 stale‑issue 機器人。
同類工具的資源管理對比
GitHub Copilot 作為 VS Code 擴充套件執行,受到擴充宿主的記憶體限制和生命週期管理約束;Cursor 基於 VS Code 的 fork,繼承了相同的資源管理框架;兩者的儲存都使用 SQLite 或類似的資料庫,天然支援並發和交易。Claude Code 選擇了獨立程序 + 扁平檔案的方案,卻沒有實現獨立程序應有的資源管理責任 —— 沒有記憶體上限,沒有磁碟配額,沒有程序看門狗,沒有優雅退出。它的行為更像一個原型示範,而不是一個面向生產環境的工具。
模型能力與工程品質的悖論
11.3MB 的單檔打包、413 個同步檔案系統呼叫、1087 個 CJS/ESM 互操作包裝器、沒有資源清理、沒有並發控制、沒有磁碟空間監控 —— 這些不是邊緣 case,而是系統性的架構缺陷。從 2025 年 8 月的 Issue #5024 到 2026 年 4 月的 Issue #44507,社群持續報告相同類別的問題,提供詳盡的分析和修復建議,而許多 issue 被標記為「not planned」或被 stale 機器人自動關閉。一個 AI 編碼工具,其自身的程式碼品質卻需要社群來稽核和修復,這本身就是一個值得深思的悖論。
如果你正在使用 Claude Code,建議定期檢查 ~/.claude 目錄大小,清理暫存目錄中的 .node 檔案,並在關閉終端前確保使用 Ctrl+C 正確退出。若磁碟空間突然消失,現在你至少知道該去哪裡找原因了。