Community编程与开发github.com

OpenClaw测试堆内存泄漏分析

用于调查OpenClaw pnpm测试中的内存增长、Vitest OOM、RSS尖峰以及堆快照差异问题。

OpenClaw测试堆内存泄漏分析 是什么?

该技能用于分析和诊断OpenClaw项目测试过程中的内存泄漏问题,特别是针对pnpm测试中的内存增长、Vitest的OOM(内存不足)错误、RSS(常驻集大小)异常尖峰以及堆快照差异。它帮助开发者区分真正的内存泄漏与共享工作进程生命周期问题,并提供一套完整的工作流程:从复现失败场景、收集堆证据、分类增长类型到修复和验证。技能支持多种平台(CLI、开发工具),并包含快照比较脚本(heapsnapshot-delta.mjs)和专用的运行时修复验证工具(embedded-run-abort-leak)。通过本技能,用户可以精确诊断模块图增长还是应用对象泄漏,避免误判,并根据证据定位正确的修复层。

兼容平台✓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 以获取最新的测试性能命令和证据路由。

针对运行时修复(例如网关等长期运行服务中的闭包泄漏),请参见下面的验证运行时修复部分——该部分使用专用的测试框架,而非单元测试性能分析工作流。

工作流

  1. 首先复现失败的形态。

    • 匹配真实的入口点和工作进程预算。要获得基础粒度的单元快速基线(包含每个配置的最大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配置或分片,并在报告与配置或工作进程预算相关时保留该形态。

  2. 收集最强的可用堆证据。

    • 运行 pnpm test:perf:profile:runner -- --output-dir .artifacts/test-perf/vitest-runner-profile -- <file> 获取CPU性能分析以及单元运行器的采样堆分析。在DevTools中打开堆分析并检查最大的分配家族。
    • 采样的 .heapprofile 输出不是 .heapsnapshot;不要将其传递给快照差异工具。
    • 当专用测试框架或其他已知生产者生成重复的 .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配置或分片启动且受影响的测试完成。

启发式规则

  • 不要将所有增长都称为泄漏。在非隔离的共享Vitest项目中的增长可能是工作进程生命周期问题,而非应用对象泄漏。
  • scripts/test-projects.mts、scripts/test-group-report.mts 和 scripts/run-vitest-profile.mts 分别是当前执行、分组RSS和性能分析的入口点。
  • [test] starting ... 行标识了要复现的Vitest配置或分片。
  • .artifacts/vitest-shard-timings.json 存储了配置/分片的执行时长用于调度。它不是文件级内存热点或行为清单。
  • 当同一保留对象族在同一个工作进程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工作进程内存增长。对于验证运行时/闭包修复是否确实释放了捕获的状态,请使用专用测试框架:

  • pnpm leak:embedded-run — 运行 scripts/embedded-run-abort-leak.ts。在一个模拟 runEmbeddedAttempt 的函数作用域内循环N次中止运行,写入堆快照,并通过基于 FinalizationRegistry 的跟踪实例计数和RSS差异,给出关于保留增长通过/未通过的结论。

模式:

  • closure-extracted(默认)— 生产修复形态(模块作用域的辅助函数)。
  • closure-inline — 修复前形态(运行器作用域内的闭包)。用作敏感性检查:如果它通过了,说明你破坏了测试框架而非修复了Bug。
  • synthetic-leak — 通过模块级别的桶故意保留对象。用于确认测试框架能够检测泄漏,然后再信任真实修复的通过结果。

快照存储在 .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

当修复其他运行时泄漏时,请在此旁边添加新的测试框架,而不是改造此框架。夹具函数应模拟泄漏所在函数的词法作用域,而不是一个通用的中止循环。

输出期望

使用本技能时,请报告:

  • 确切的复现命令。
  • 复现了哪个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.

相关技能