Community程式設計與開發github.com

openclaw-test-heap-leaks

調查 OpenClaw pnpm 測試的記憶體增長、Vitest OOM、RSS 峰值以及堆快照差異。

openclaw-test-heap-leaks 是什麼?

此技能專為調查 OpenClaw 專案中 pnpm 測試工作階段的記憶體問題而設計。它能協助開發者診斷 Vitest 發生的記憶體不足(OOM)錯誤、RSS 異常峰值,以及透過 heap snapshot 差異分析來找出記憶體洩漏的根源。支援平台包括 Vitest 測試框架,並整合了 OpenClaw 的測試效能工具鏈與自訂腳本。其運作方式分為五大步驟:重現失敗模式、收集最強烈的堆記憶體證據、分類記憶體增長原因、修復正確的問題層級,以及驗證修復效果。它特別強調不應僅憑 RSS 猜測,而應優先使用 heap snapshot 或 heap profile 進行佐證。此外,它也提供專門的驗證 harness 來測試生產環境中的閉包洩漏修復,並內建快照比較工具,能自動選取同一 PID 的相關快照進行比對。此工具對於區分因 shared worker 生命週期造成的「假性增長」與真正的「物件洩漏」至關重要,並能引導開發者檢視 retainers/dominators 以確認根本原因。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/clawdbot/clawdbot/tree/main/.agents/skills/openclaw-test-heap-leaks

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

OpenClaw 測試堆記憶體洩漏

使用此技能進行測試記憶體調查。當有堆快照可用時,請勿僅根據 RSS 進行猜測。將快照名稱的差異視為初步分類證據,而非最終證明,除非有 retainers 或 dominators 支持此結論。

請先閱讀 ../openclaw-test-performance/SKILL.md,以了解當前的測試效能命令和證明路由。

對於執行時期修復(例如,長期運行的服務如 gateway 中的閉包洩漏),請參閱下方的驗證執行時期修復 —— 該部分使用的是專用 harness,而非單元測試剖析工作流程。

工作流程

  1. 首先重現失敗的型態。

    • 匹配真實的進入點和工作執行緒(worker)預算。若要取得廣泛的 unit-fast 基線(包含各設定的最大 RSS 和頂層檔案計時),請從以下指令開始:

      pnpm test:perf:groups \
        --config test/vitest/vitest.unit-fast.config.ts \
        --allow-failures \
        --output .artifacts/test-perf/unit-fast-memory.json
      
    • 針對可疑的檔案,使用一個工作執行緒重新執行該檔案,並收集 wall/RSS 證據:/usr/bin/time -l pnpm test <file> --maxWorkers=1 --reporter=verbose。

    • 目前的 pnpm test 執行是由 scripts/test-projects.mts 規劃。請記錄印出的 Vitest 設定或 shard,並在報告與設定或工作執行緒預算相關時保留該型態。

  2. 收集最強烈的可用堆記憶體證據。

    • 執行 pnpm test:perf:profile:runner -- --output-dir .artifacts/test-perf/vitest-runner-profile -- <file> 以取得單元執行器的 CPU 剖析和取樣堆記憶體剖析。在 DevTools 中開啟堆記憶體剖析,檢查最大的配置系列。
    • 取樣的 .heapprofile 輸出並非 .heapsnapshot;請勿將其傳遞給快照差異輔助工具。
    • 當專用 harness 或其他已知產生器產生重複的 .heapsnapshot 檔案時,使用 .agents/skills/openclaw-test-heap-leaks/scripts/heapsnapshot-delta.mjs 比較來自相同 PID 的快照。
    • 如果沒有可用的快照或堆記憶體剖析,RSS 增長是很有用的初步分類證據,但請將洩漏分類保留為「非結論性」。
  3. 在選擇修復方式之前,先對增長進行分類。

    • 如果增長主要由 Vite/Vitest 轉換後的原始字串、Module、system / Context、位元組碼、描述符陣列或屬性映射主導,則將其視為長期執行的工作執行緒中可能的保留模組圖增長。
    • 如果增長主要由應用程式物件、快取、緩衝區、伺服器控制代碼、計時器、模擬狀態、sqlite 狀態或類似的執行時期物件主導,則將其視為可能的清理或生命週期洩漏。
    • 如果名稱不明確,請在檢查 DevTools 中頂層差異的 retainers/dominators 之前,不要做出確定的標籤。
  4. 修復正確的層級。

    • 對於共享工作執行緒中可能的保留轉換模組增長:
      • 檢查所屬的 Vitest 設定和 scripts/test-projects.test-support.mjs 中的程序分塊。僅在相同型態的證據顯示共享工作執行緒保留是原因時,才在那裡修復程序生命週期或專案所有權。
      • test/vitest/vitest.unit-fast-isolated.config.ts 用於需要全新模組圖的經審計的狀態化測試。請勿將其用作通用的記憶體熱點列表。
    • 對於真正的洩漏:
      • 修補受影響的測試或執行時期清理路徑。
      • 尋找遺漏的 afterEach/afterAll、模組重置間隙、保留的全域狀態、未釋放的資料庫控制代碼,或存活超過檔案範圍的監聽器/計時器。
  5. 使用最直接的證據進行驗證。

    • 重新執行相同的分組或限定範圍命令,並確認最大 RSS 趨勢或 OOM 已減少。
    • 當專用產生器發出堆記憶體剖析或快照時,重複相同的產生器並比較等效的產出物。
    • 對於路由或設定更改,請驗證預期的 Vitest 設定或 shard 已啟動,且受影響的測試已完成。

啟發法則

  • 不要將所有增長都稱為洩漏。在非隔離的共享 Vitest 專案中的增長,可能是工作執行緒生命週期問題,而非應用程式物件洩漏。
  • scripts/test-projects.mts、scripts/test-group-report.mts 和 scripts/run-vitest-profile.mts 是目前的執行、分組 RSS 和剖析進入點。
  • [test] starting ... 行標識了要重現的 Vitest 設定或 shard。
  • .artifacts/vitest-shard-timings.json 儲存 config/shard 的持續時間以進行排程。它不是檔案級別的記憶體熱點或行為清單。
  • 當相同的保留物件系列在同一 Worker PID 的多個間隔中增長時,請相信快照而非直覺,然後使用 retainer 證據來確認不明確的調用。

快照比較

  • 直接比較:
    • node .agents/skills/openclaw-test-heap-leaks/scripts/heapsnapshot-delta.mjs before.heapsnapshot after.heapsnapshot
  • 在同一通道中自動選取每個 PID 最早/最晚的快照:
    • node .agents/skills/openclaw-test-heap-leaks/scripts/heapsnapshot-delta.mjs --lane-dir <snapshot-directory>
  • 有用的標誌:
    • --top 40
    • --min-kb 32
    • --pid 16133

先閱讀正向最大的差異。模組轉換產出物的大量正向增長指向共享程序生命週期或專案所有權問題;執行時期物件的大量正向增長則暗示真正的洩漏。如果僅憑名稱無法解決問題,請在 DevTools 中開啟相同的快照對,檢查頂層行的 retainers/dominators,然後再宣告根本原因。

驗證執行時期修復(非測試記憶體)

以上工作流程適用於診斷 Vitest 工作執行緒記憶體增長。若要驗證執行時期/閉包修復實際上是否釋放了捕獲的狀態,請使用專用 harness:

  • pnpm leak:embedded-run — 執行 scripts/embedded-run-abort-leak.ts。在模仿 runEmbeddedAttempt 的函數作用域中循環執行 N 個中止的執行,寫入堆快照,並使用 FinalizationRegistry 追蹤實例計數加上 RSS 差異,報告關於保留增長的 PASS/FAIL 判定。

模式:

  • closure-extracted(預設)— 生產環境修整形狀(helper 在模組作用域)。
  • closure-inline — 修復前形狀(閉包在執行器作用域內)。用作敏感性檢查:如果它通過了,表示你破壞了 harness,而非修復了錯誤。
  • synthetic-leak — 透過模組級別的儲存桶故意保留。用於在相信對真正修復的 PASS 判定之前,確認 harness 能夠檢測到洩漏。

快照存放在 .tmp/embedded-run-abort-leak/。使用與上述相同的腳本進行差異比較:

node .agents/skills/openclaw-test-heap-leaks/scripts/heapsnapshot-delta.mjs \
  .tmp/embedded-run-abort-leak/baseline-*.heapsnapshot \
  .tmp/embedded-run-abort-leak/batch-N-*.heapsnapshot --top 30

在修復不同的執行時期洩漏時,請在此 harness 旁新增一個新的 harness,而不是對其進行改造。確保 fixture 函數模擬洩漏所在函數的詞法作用域,而不是一個通用的中止循環。

輸出預期

使用此技能時,請回報:

  • 精確的重現指令。
  • 重現了哪個 Vitest 設定或目標,以及當快照可用時,比較的是哪個 PID。
  • 當可用時,來自堆記憶體剖析或快照差異的主要保留物件系列。
  • 問題是可能真正的洩漏,還是可能共享工作執行緒保留模組增長,以及 retainers/dominators 是否確認了這一點。
  • 具體的修復或影響減少補丁。
  • 你驗證了什麼,以及哪些快照開銷阻止了你進行驗證。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

1password

Set up and use 1Password CLI for sign-in, desktop integration, and reading or injecting secrets.

acp-router

Route plain-language requests for Claude Code, Cursor, Copilot, OpenClaw ACP, OpenCode, Gemini CLI, Qwen, Kiro, Kimi, iFlow, Factory Droid, Kilocode, or explicit ACP harness work into either OpenClaw ACP runtime sessions or direct acpx-driven sessions ("telephone game" flow). For coding-agent thread requests, read this skill first, then use only `sessions_spawn` for thread creation. Codex chat binding defaults to the native Codex app-server plugin unless ACP is explicit or background spawn needs ACP.

add-model-provider

Add and live-prove a model provider with non-interactive config one-liners, without exposing credentials.

agent-transcript

Requested GitHub PR/issue agent transcripts: redact, trim, preview, and insert safely.

apple-notes

Create, view, edit, delete, search, move, or export Apple Notes via the memo CLI on macOS.

apple-reminders

List, add, edit, complete, or delete Apple Reminders and reminder lists via remindctl.

auto-qa

Run OpenClaw-wide autonomous QA and live/stress campaigns across independent subsystem lanes, with verified fixes and a resumable evidence report.

autoreview

Structured code review through the shared OpenClaw agent-skills installation.

bear-notes

Create, search, and manage Bear notes via grizzly CLI.

blacksmith-testbox

Run Blacksmith Testbox for CI-parity checks, secrets, hosted services, migrations, or builds local cannot reproduce.

block-kit

Use proactively for structured or interactive Slack replies, and when asked to author or validate native Slack Block Kit JSON.

blogwatcher

Monitor blogs and RSS/Atom feeds for updates using the blogwatcher CLI.

blucli

BluOS CLI (blu) for discovery, playback, grouping, and volume.

bluebubbles

Send and manage iMessages via BlueBubbles, including attachments, tapbacks, edits, replies, and groups.

browser-automation

Use when controlling web pages with the OpenClaw browser tool, especially multi-step flows, login checks, tab management, or recovery from stale refs/timeouts.

camsnap

Capture frames or clips from RTSP/ONVIF cameras and local webcams, including USB pan/tilt/zoom control.

canvas

Present HTML on connected OpenClaw node canvases, navigate/eval/snapshot, and debug canvas host URLs.

channel-message-flows

Use when running QA Lab channel message flow evidence.

clawdtributor

Clawtributor PRs here, last week or another window: discover conversation refs, recheck GitHub, rank by impact.

clawhub

Search ClawHub for plugins by default, or skills when explicitly requested; install, verify, update, uninstall, publish, or sync skills.

相關技能