en un clic
memory-leak-debug
// Diagnose memory leaks in the Qwen Code CLI using heap snapshots and the chrome-devtools CLI. Use when investigating high memory usage, unbounded growth, or suspected object retention issues.
// Diagnose memory leaks in the Qwen Code CLI using heap snapshots and the chrome-devtools CLI. Use when investigating high memory usage, unbounded growth, or suspected object retention issues.
Review changed code for correctness, security, code quality, and performance. Use when the user asks to review code changes, a PR, or specific files. Invoke with `/review`, `/review <pr-number>`, `/review <file-path>`, or `/review <pr-number> --comment` to post inline comments on the PR.
Diagnose frozen, stuck, or slow Qwen Code sessions on this machine. Scans for problematic processes, high CPU/memory usage, hung subprocesses, and debug logs. Use /stuck or /stuck <PID> to focus on a specific process.
This skill should be used when the user asks to "用 tmux 做真实测试", "保存 tmux 日志", "像真实用户一样测试 Qwen", "生成可复查的 TUI 测试报告", "测试 slash command 交互", or requests a tmux-based real user E2E run with complete readable logs. It guides real TUI usage with step-by-step capture-pane snapshots rather than ANSI raw pipe logs.
Execute batch operations on multiple files in parallel. Automatically discovers files, splits into chunks, and processes with parallel worker agents. Use `/batch` followed by operation and file pattern.
Create a recurring loop that runs a prompt on a schedule. Usage - /loop 5m check the build, /loop check the PR every 30m, /loop run tests (defaults to 10m). /loop list to show jobs, /loop clear to cancel all.
Answer any question about Qwen Code usage, features, configuration, and troubleshooting by referencing the official user documentation. Also helps users view or modify their settings.json. Invoke with `/qc-helper` followed by a question, e.g. `/qc-helper how do I configure MCP servers?` or `/qc-helper change approval mode to yolo`.
| name | memory-leak-debug |
| description | Diagnose memory leaks in the Qwen Code CLI using heap snapshots and the chrome-devtools CLI. Use when investigating high memory usage, unbounded growth, or suspected object retention issues. |
Diagnose memory leaks in the Qwen Code Node.js CLI by capturing heap snapshots
and analyzing retained object sizes via chrome-devtools CLI tooling.
chrome-devtools CLI (from chrome-devtools-mcp package). If not found,
install with: npm i chrome-devtools-mcp@latest -g after user confirmation.
See https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/docs/cli.md--heapsnapshot-signal support)Use tmux so you can interact with the TUI and trigger snapshots from another pane. Use the tmux-real-user-testing helper script:
HELPER=.qwen/skills/tmux-real-user-testing/scripts/tmux-real-user-log.sh
eval "$(bash "$HELPER" start memleak . \
env QWEN_CODE_NO_RELAUNCH=true NODE_OPTIONS=--heapsnapshot-signal=SIGUSR2 \
npm run dev)"
echo "SESSION=$SESSION OUTDIR=$OUTDIR"
The eval exports SESSION and OUTDIR. Note: shell environment does not
persist across separate tool calls — save the session name from the output and
use it explicitly in subsequent commands.
Notes:
npm run dev runs from TypeScript source via tsx — no build step needed and
changes to core/cli are reflected immediately.QWEN_CODE_NO_RELAUNCH=true prevents the CLI from spawning a child process,
so PID management is simpler.NODE_OPTIONS propagates the flag through npm → tsx → node.Get the PID of the actual node process. With npm run dev, there's a process
chain (npm → node scripts/dev.js → tsx → node CLI), so walk the tree to the
innermost node child:
NODE_PID=$(bash .qwen/skills/memory-leak-debug/scripts/find-leaf-node.sh "<session-name>")
To profile the production bundle instead (e.g., verifying tree-shaking):
npm run bundle first, then use
env QWEN_CODE_NO_RELAUNCH=true node --heapsnapshot-signal=SIGUSR2 dist/cli.js
as the command. Since node is the direct pane process, PID discovery is simpler:
NODE_PID=$(tmux list-panes -t "<session-name>" -F '#{pane_pid}')
Drive the TUI via tmux (see tmux-real-user-testing skill for patterns). Take snapshots at intervals to compare:
kill -USR2 $NODE_PID # snapshot 1 (baseline)
# ... use the CLI via tmux send-keys ...
kill -USR2 $NODE_PID # snapshot 2 (after activity)
# ... more activity ...
kill -USR2 $NODE_PID # snapshot 3 (confirm growth trend)
Snapshots are written to the CLI's working directory as
Heap.<timestamp>.<pid>.<seq>.heapsnapshot.
chrome-devtools start --experimentalMemory --headless --no-usage-statistics
This starts the daemon in file-analysis mode — no browser or live Node
connection is needed. The memory tools work entirely on .heapsnapshot files.
chrome-devtools load_memory_snapshot /abs/path/to/snapshot.heapsnapshot
Returns total heap size, V8 heap breakdown, node count.
chrome-devtools get_memory_snapshot_details /abs/path/to/snapshot.heapsnapshot
Output is CSV: uid, className, count, selfSize, maxRetainedSize.
Compare across snapshots to find classes whose count or retained size grows unboundedly.
chrome-devtools get_nodes_by_class /abs/path/to/snapshot.heapsnapshot <uid>
Where <uid> is from the get_memory_snapshot_details output. Returns
individual instances with their id, retainedSize, and nodeIndex.
chrome-devtools get_node_retainers /abs/path/to/snapshot.heapsnapshot <nodeId>
Where <nodeId> is the id field from get_nodes_by_class. Shows what holds
the object alive — follow the chain to find the root retention path.
Common patterns:
performance.measure() → measureEntryBuffer).The retainer chain tells you what holds the object; the class aggregate growth rate tells you how fast it leaks.
After applying the fix:
npm run bundleHELPER=.qwen/skills/tmux-real-user-testing/scripts/tmux-real-user-log.sh
bash "$HELPER" finish "<session-name>" "<outdir>"
chrome-devtools stop
rm *.heapsnapshot # if no longer needed
See examples/react-reconciler-performance-measure-leak.md for the ink 7
upgrade leak that caused ~143 MB retention from PerformanceMeasure objects.