内存泄漏调试
本技能提供了使用 Chrome DevTools MCP 工具查找、诊断和修复 JavaScript 与 Node.js 应用中内存泄漏的专业指导和工作流程。
前提条件
高级内存调试工具(compare_heapsnapshots、get_heapsnapshot_details 等)仅在服务器以 --memoryDebugging 标志启动时可用。首先检查这些工具是否可用;如果不可用,请尝试读取 MCP 配置文件以检查是否启用了 --memoryDebugging。
核心原则
- 优先使用 MCP 内存工具: 请勿尝试直接读取原始的
.heapsnapshot文件,因为它们体积巨大,会消耗过多 token。请使用 Chrome DevTools MCP 堆快照工具来汇总、比较和检查快照。 - 隔离泄漏源: 确定泄漏是发生在浏览器端(客户端)还是 Node.js(服务器端)。
- 常见元凶: 查找分离的 DOM 节点、未清理的闭包、全局变量、未被移除的事件监听器以及无限制增长的缓存。注意:分离的 DOM 节点有时是有意为之的缓存;在清空它们之前务必询问用户。
- 关闭已加载的快照: 堆快照可能很大。完成调查后,请为每个已加载的快照使用
close_heapsnapshot,以释放 MCP 服务器占用的内存。
工作流程
1. 捕获快照
在调查前端 Web 应用内存泄漏时,利用 chrome-devtools-mcp 工具与应用交互并拍摄快照。
- 使用页面级工具,如
click、navigate_page、fill等(指定pageId)将页面操作为所需状态。 - 在交互后将页面恢复到原始状态,观察内存是否被释放。
- 重复相同的用户交互操作 10 次以放大泄漏。
- 使用
take_heapsnapshot(带pageId)在基线状态、目标状态(操作后)和最终状态(恢复后)将.heapsnapshot文件保存到磁盘。
2. 比较快照
一旦使用 take_heapsnapshot 生成了 .heapsnapshot 文件,即可使用 Chrome DevTools MCP 内存工具进行比较。
- 首先对每个快照使用
get_heapsnapshot_summary,确认文件正常加载并对比高级别的总计数据。 - 使用
compare_heapsnapshots比较基线和目标快照。先不带classIndex参数获取汇总差异,然后仅对可疑的增长指定classIndex请求详细的类差异。 - 在深入特定节点 ID 之前,先分析
compare_heapsnapshots的输出摘要。
3. 检查保留器和 Dominator 链
当某个类或对象类型出现意外的增长时,在修改代码之前使用 MCP 工具检查保留链和 Dominators。
- 使用
get_heapsnapshot_class_nodes列出可疑类的所有实例。 - 使用
get_heapsnapshot_retainers、get_heapsnapshot_retaining_paths、get_heapsnapshot_dominators和get_heapsnapshot_edges了解代表性节点为何仍然可达。 - 使用
get_heapsnapshot_object_details(指定nodeId)检索详细的对象元数据(大小、类型、距离以及 DOM 分离状态)。 - 当字符串增长主导差异时,使用
get_heapsnapshot_duplicate_strings。 - 阅读 references/common-leaks.md,了解常见内存泄漏的示例以及当保留路径指向应用代码时的修复方法。
4. 高级分析与分类过滤器
直接使用内置的 MCP 内存工具和过滤器,无需外部工具即可定位特定的泄漏类别。
- 使用
get_heapsnapshot_details或get_heapsnapshot_class_nodes(带filterName)针对常见的泄漏原因:objectsRetainedByDetachedDomNodes:识别内存中保留的分离 DOM 元素。objectsRetainedByEventHandlers:识别因未移除的事件监听器而保持存活的对象。objectsRetainedByContexts:识别被闭包或执行上下文捕获的对象。objectsRetainedByConsole:识别因控制台日志而保留的对象。