关于 memorydetective
memorydetective 是用于调查 iOS 内存泄漏和性能问题的 MCP 服务与命令行工具,可分析 memgraph 文件、轨迹和 MetricKit 诊断数据。它帮助开发者检查循环引用、卡顿等问题,并支持在模拟器中复现问题及验证修复。
主要功能
- 01分析并分类 memgraph 循环引用
- 02检查轨迹中的卡顿、内存和性能
- 03分析 MetricKit 诊断负载
- 04捕获并重放模拟器场景
- 05对比内存图并验证修复
适用场景
- 01将循环引用定位到可能的 SwiftUI 或 Combine 模式
- 02查找 iOS 轨迹中的卡顿热点
- 03检查 MetricKit 文件中的崩溃和卡顿集群
- 04对比代码变更前后的内存图
MCP 相关
MCP 服务向 MCP 客户端提供分析、捕获、对比和修复验证工具,并提供 summarize-trace 提示词。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
42收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | `.memgraph` 文件的绝对路径(从 Xcode Memory Graph Debugger 导出)。 |
| verbosity | enum | 否 | 类名详细程度。`compact`(默认)会移除模块前缀,将嵌套的 SwiftUI ModifiedContent 折叠为 `+N modifiers`,并使用哈希占位符截断深层泛型。`normal` 保留更多细节。`full` 按原样返回 Swift 去混淆名称。compact | normal | full |
| fullChains | boolean | 否 | 为 true 时,在响应中包含完整的嵌套保留链。默认值 false 仅返回顶层 ROOT CYCLE 摘要,以保持负载较小。 |
| outputFormat | enum | 否 | 响应格式。省略或设为 `json`(默认,保留 v1.8 行为)时,返回结果的 JSON.stringify。`markdown` 会以易读形式呈现相同数据。`both` 会在一个响应中返回两种内容项,客户端可向用户显示 markdown,并为 Agent 循环解析 JSON,无需再次调用。`verify-fix-table`(v1.10,适用于 `analyzeAbandonedMemory` 和 `diffMemgraphs`)会生成一个聚焦于可操作行的 4 列 markdown 对比表(Class | Before | After | Delta);其他工具遇到此值时会回退为 `markdown`。markdown | json | both | verify-fix-table |
| maxClassesInChain | integer | 否 | 每个 cycle 的 `classesInChain` 数组中最多显示多少个唯一类名。默认值为 10,足以识别应用级类型,同时不会让响应过于冗长。 |
| referenceTreeTopN | integer | 否 | 当 `leakCount` 为 0(典型的内存遗弃情况)时,也运行 `leaks --referenceTree --groupByType --noContent`,并在 `abandonedMemoryTop[]` 中显示存活实例数最多的前 N 个类。设为 0 可跳过第二次 leaks 调用。默认值为 20。 |
详细介绍
memorydetective
English · 巴西葡萄牙语
在聊天窗口中诊断 iOS 循环引用和性能回退。无需 Xcode。

亮点
- **通过命令行工具查找内存泄漏。**读取由 Xcode 捕获的
.memgraph文件(或由memorydetective在模拟器上自行捕获的文件),查找根循环引用,根据已知的 SwiftUI/Combine 模式对其进行分类,并提供一句话修复建议。整个过程都可通过脚本或聊天完成。 - **原生支持 MCP。**可接入 Claude Code、Claude Desktop、Cursor、Cline 和其他任何 MCP 客户端。Agent 可完成从调查到分类再到提出修复建议的完整流程,无需打开 Instruments。
- **如实说明自身限制。**不伪造输出,也不夸大能力。挂起分析可通过
xctrace正常运行;如果xctrace能为跟踪记录添加符号信息,则会解析样本级 Time Profile;如果不能,则会返回结构化的变通方案说明(重型未添加符号信息的跟踪记录可能导致底层xctrace发生 SIGSEGV,这是 Apple 方面的限制,我们会明确说明)。可在 Mac 应用和 iOS 模拟器上捕获内存图;实体 iOS 设备仍需要 Xcode。
v1.18 新内容(2026-05-17):MetricKit + audit-close。
analyzeMetricKitPayload是第 42 个 MCP 工具:可接收来自真实设备 TestFlight / App Store 构建的 Apple MetricKit.mxdiagnosticJSON 负载(用于事后生产诊断,目前没有其他 MCP 竞品覆盖这一领域)。提供三类可操作的输出:按异常类型 / 二进制文件 / 顶层帧分组的崩溃集群、支持本地化时长解析("5.4 sec"/"20秒")的卡顿热点,以及 CPU + 磁盘异常。还提供跨工具链路提示(例如,出现类似objc_release的顶层帧时,会建议使用findCycles)。此外还完成了三个审计收尾事项:开放枚举SupportStatusKind(下游使用者可新增类型,而无需进行破坏性类型升级)、调用范围内的schemaDiscovery缓存(通过一次性预先获取 TOC,在真实 Apple 跟踪数据上将summarizeTrace的端到端耗时从约 28 秒缩短至约 15 秒),以及针对真实 Apple.trace包的仅限本地集成测试(彻底解决 v1.14 的 P+O 漂移问题)。测试数量从 701 增至 757。MCP 工具数量从 41 增至 42。近期内容(v1.17):可靠性改进。分三个层级修复了 14 个 Bug。重点包括:strtobool 环境变量真值解析、
verifyFix白名单匹配模式(精确 / 子字符串 / 正则表达式)、recordViaInstrumentsApp可捕获保存在watchDir之外的跟踪文件、inspectTrace容错回退、可配置的countAlive框架噪声过滤器,以及可变大小类的最小值 / 最大值 / 中位数。以及 v1.16:macOS 26.x 录制解阻版本。新增的
recordViaInstrumentsAppMCP 工具封装了 Instruments.app 图形界面流程:打开应用、显示分步说明、监视目录中保存的.trace,并在成功后接续调用inspectTrace。在 Apple 修复 macOS 26.x 模拟器上的xcrun xctrace record回归问题之前,这是自动化录制方案。以及 v1.15:补齐架构覆盖 + 改进 verify-fix 体验。新增三个 MCP 跟踪工具,填补了剩余的架构缺口:
analyzeMemoryFootprint(第 38 个,用于诊断 VM 常驻 / 脏页 / 虚拟内存 + jetsam)、analyzeEnergyImpact(第 39 个,用于调查电池耗电)、analyzeLeakTimeline(第 40 个,将 xctrace 的 leaks 工具作为时间序列呈现)。summarizeTrace现在会接续调用analyzeNetworkActivity。replayScenario会为每个步骤截取模拟器屏幕截图。更早的内容:v1.14 改进跟踪侧可靠性,新增
analyzeNetworkActivity、统一的supportStatus[]、受 FLEX 启发的countAlive大小视图,以及受 MLeaksFinder + DebugSwift 启发的verifyFix白名单。v1.13 发布了summarizeTrace+/summarize-traceMCP 提示词。v1.12 完成了引用树传播。v1.11 新增 inspectTrace、diffMemgraphs 引用树。v1.9 发布了 analyzeAbandonedMemory、detectLeaksInXCTest、cleanupTraces、mainThreadViolations。完整说明见 CHANGELOG。
**macOS 26.x 用户请注意:**Apple 在 macOS 26.x 中引入了
task_for_pid内核回归问题,导致针对 iOS 模拟器进程执行leaks --outputGraph、heap和xctrace --template Allocations均会受阻,与MallocStackLogging无关。除非在方案的 Diagnostics 标签页中启用Malloc Stack Logging,否则连 Xcode 的“View Memory Graph Hierarchy”也会遇到此问题。memorydetective 会在首次调用捕获类工具时主动提示platformAdvisory;如果调用了leaks,还会提供包含issue: "macos-26-task-for-pid-broken"的workaroundNotice。目前最可靠的解决方法是使用 iOS 18 模拟器运行时(通过 Xcode > Settings > Platforms > +iOS 18.x 安装)。在 2026-05-12 的 notelet 调查中已通过实证验证:三种彼此独立的 CLI 内存检查路径均告失败,之后才发现 iOS 18 是可行的替代方案。选定解决方法后,可设置MEMORYDETECTIVE_SUPPRESS_PLATFORM_ADVISORY=1来关闭提示。 macOS 26.x 上也会遇到:模拟器目标的xctrace record已损坏。 独立于上述task_for_pid回归问题,针对 iOS 模拟器进程运行xcrun xctrace record --time-limit Ns会卡住并超出时间限制,最终在被终止时退出,生成的.trace包缺少模板元数据。随后运行xctrace export --toc会报错Document Missing Template Error。2026-05-15 在 Xcode 26.5(build 17F42,xctrace 16.0)上重新验证:更新后回归问题依然存在。整个基于xctrace的生态都会以相同方式受影响(memorydetective.recordTimeProfile、XcodeTraceMCP,以及直接调用xcrun xctrace record都会出现相同故障)。解决方法:(1)使用recordViaInstrumentsApp(v1.16 提供,v1.17 加固),它会为你打开 Instruments.app,提示你录制并保存.trace,然后在检测到该包后自动调用inspectTrace。v1.17 还会通过 Instruments.app AppleScript 文档查询捕获保存到监视目录之外的情况,并返回savedOutsideWatchDir: true和实际路径;(2)如果有搭载 Xcode 26.0 的旧版 macOS 主机,可在其上录制;(3)对实体设备进行录制(该回归问题似乎只影响模拟器)。v1.17 为recordTimeProfile添加了可行性探测(磁盘上的包为 52K 占位文件时,bundleStatus: "wedged"),也为inspectTrace添加了可行性探测(返回包含诊断文本的ok: true,而不是抛出错误)。USAGE.md > Troubleshooting 中提供了分步说明。
快速入门
npm install -g memorydetective
添加到你的 MCP 客户端配置中(以下示例使用 Claude Code):
// ~/.claude/settings.json
{
"mcpServers": {
"memorydetective": { "command": "memorydetective" }
}
}
也可以直接通过命令行使用:
memorydetective analyze ~/Desktop/myapp.memgraph
memorydetective classify ~/Desktop/myapp.memgraph
→ 聊天驱动流程见 示例 · 完整工具参考见 API · Claude Desktop / Cursor / Cline 配置见 配置 · 完整操作指南见 USAGE.md,其中包括如何将修复从诊断应用到你的代码库。
示例
真实场景的聊天片段。Agent 会调用 API 中列出的 MCP 工具。
从内存图诊断泄漏
你: 我刚导出了一个内存图,路径是
~/Desktop/example.memgraph。关闭详情页后似乎有东西在泄漏。是什么?Claude: (调用
analyzeMemgraph→classifyCycle) 在 60,436 个泄漏中发现了 4 个 ROOT CYCLE 块。其中占主导的一个高度匹配 swiftui.tag-index-projection。照片轮播的ForEach上通过.tag()附加的闭包通过_viewModel.wrappedValue强引用了self,导致DetailViewModel和导航协调器在关闭页面后仍然存活。建议的修复: 将点击处理器中的
[weak self]捕获替换为静态辅助方法,或通过[weak coord = self.coordinator]弱引用捕获视图模型。要我帮你查找具体文件吗?
验证修复是否生效
你: 我已经发布了修复。比较一下
~/Desktop/before.memgraph和~/Desktop/after.memgraph,告诉我DetailViewModel的数量是否减少。Claude: (调用
diffMemgraphs→countAlive)DetailViewModel:12 → 0(变化量-12)。swiftui.tag-index-projection循环已消失。泄漏总数从 60,436 降至 55,576(−4,860)。另外 3 个 ROOT CYCLE 仍然存在。这些是 SwiftUI 内部问题,不是你的代码。
自包含的验证修复闭环(v1.8)
当 leaks --outputGraph 在 macOS 26.x 上失败(Failed to get DYLD info for task)时,通常是因为启动应用时没有设置 MallocStackLogging=1。新的编排工具可以端到端处理整个流程,无需你自行串联 xcodebuild、simctl 和 axe。
**你:**帮我在
MyApp中复现内存泄漏。先构建应用,用正确的环境变量启动,再重复执行照片轮播流程 5 次以放大问题,然后捕获修复前的状态;我发布修复后,你再捕获修复后的状态。Claude:(调用
bootAndLaunchForLeakInvestigation) 已构建并启动 iPhone 15(UDIDABCD-...)。已启动MyApp(PID49581),并设置MallocStackLogging=1。Bundle ID 为com.example.MyApp。(调用
replayScenario,执行 5 次轮播点击和返回按钮操作循环,再重复 5 次) 已在 12.3 秒内执行 25 项操作。无失败。(调用
captureScenarioState({label:"before"})) 已写入before.memgraph(63,201 个泄漏)、before.png、before.ui.json。MallocStackLogging已启用,无 workaroundNotice。(你发布修复并重新构建)
(调用
bootAndLaunchForLeakInvestigation+ replay +captureScenarioState({label:"after"}))(调用
diffMemgraphs→verifyFix)DetailViewModel:15 → 0。swiftui.tag-index-projectionPASS。释放字节数:28.4 MB。
在真机上查找耗时路径
**你:**在我的 iPhone 上分析 DemoApp 90 秒,并告诉我卡顿出在哪里。
Claude:(调用
listTraceDevices→recordTimeProfile→analyzeHangs) 已录制~/Desktop/run.trace(90 秒,连接到 iPhone 17 Pro Max 上的 DemoApp)。发现 23 次用户可见卡顿(每次均超过 500 ms),最长 1.16 秒,平均 769 ms。负载严重。全部发生在主线程上。样本级热点尚未完成符号化;此步骤需在 Instruments 中打开跟踪文件(当xctrace无法进行符号化时,analyzeTimeProfile会返回结构化的解决方法提示。参见 CHANGELOG 中的已知限制)。
分析真实用户崩溃的 MetricKit 负载(v1.18)
**你:**我有一个文件夹,里面是过去 30 天 TestFlight 的
.mxdiagnostic文件,路径为~/Downloads/metrickit-may/。真实用户遇到了什么问题?Claude:(调用
analyzeMetricKitPayload({ payloadDir: "~/Downloads/metrickit-may/" })) 共 47 个负载,时间范围为 2026-04-15 → 2026-05-15。主要问题:18 次 EXC_BAD_ACCESS 崩溃,集中在同一个顶层堆栈帧,全部出现在构建版本 456 和 457 中(版本 458 及更早版本均未出现)。该模式符合释放时的保留环;链路提示建议接下来调用findCycles。第二个问题:
libsqlite3.dylib中出现 5.4 秒卡顿(3 个样本)。如果你能在本地复现,可串联调用analyzeHangs,并设置includeStackClassification: true,以使用mainThreadViolations[]分类器。v1.18 中没有已符号化的堆栈帧(已提供原始
binaryUUID + offset;dSYM 查找由独立工具处理,将在未来版本推出)。已处理本地化的卡顿时长字符串:输入"5.4 sec"已规范化为 5400ms;其中一份诊断数据包含"20秒"(日语),已规范化为 20000ms。
有关完整的端到端示例,包括如何将 analyzeMetricKitPayload 接入跨多个 TestFlight 构建版本的验证修复闭环,请参阅 USAGE.md § MetricKit 生产环境事后分析。
端到端:泄漏 → 文件 → 修复建议
从问题产物到代码编辑的完整流程。结合内存图分析与 Swift 源码桥接。
你: 有个泄漏。内存图在
~/Desktop/example-leaks.memgraph。循环指向DetailViewModel。找出它在项目~/Development/myapp/中的位置,并建议修复方案。Claude: (调用
analyzeMemgraph→classifyCycle→reachableFromCycle) 找到 4 个 ROOT CYCLE 块。其中占主导的一个与swiftui.tag-index-projection匹配,置信度很高。reachableFromCycle确认有 4 个DetailViewModel实例,每个都固定保留约 1100 个NSURLSessionConfiguration。问题出在 VM,网络栈只是受牵连。(调用
swiftSearchPattern,在~/Development/myapp/Sources/中查找.tag(+onImageSliderTap模式) 在MyApp/Views/MediaCarousel.swift:142找到 1 处匹配。(调用
swiftGetSymbolDefinition({ symbolName: "DetailViewModel", projectRoot: "...", candidatePaths: ["MyApp/ViewModels/"] })) 声明位置:MyApp/ViewModels/DetailViewModel.swift:18。class DetailViewModel: ObservableObject。(调用
swiftFindSymbolReferences,确定影响范围。7 个调用点)建议在
MediaCarousel.swift:142处修复:// before .tag(index) .onImageSliderTap { index in self.viewModel.handlePhotoTap(at: index) } // after. Static helper + weak captures .tag(index) .onImageSliderTap { [weak vm = _viewModel.wrappedValue, weak coord = self.coordinator] index in Self.handlePhotoTap(index: index, viewModel: vm, coordinator: coord) }需要我应用此修复并用新的
.memgraph验证吗?
它能为你节省什么
一句话概括:memorydetective 可将 50–500 MB 的二进制内存图(或 200 KB 的 leaks(1) 文本转储)转成 2–5 KB 的结构化摘要,让 AI Agent 能够据此进行有效推理。 这改变了使用大模型调查 iOS 性能问题的成本效益。
令牌(与 Claude / Cursor / Cline 等 AI Agent 配合使用时)
对真实的循环引用问题进行调查,运行两次:一次使用 memorydetective,一次由 Agent 直接读取原始 leaks(1) 输出:
| 步骤 | 不使用 MCP(Agent 读取原始输出) | 使用 memorydetective |
|---|---|---|
加载 leaks 文本转储(约 280 KB) | 约 70,000 个输入令牌 | 不适用 |
analyzeMemgraph 摘要 | 不适用 | 约 750 个输入令牌 |
classifyCycle + 修复提示 | Agent 每次后续提问都要重新推理转储内容(额外 3–4 轮) | 1 轮,返回结构化的 patternId + fixHint |
findRetainers / reachableFromCycle | Agent 重新扫描转储内容 | 约 500 个令牌,范围限定的查询 |
| 每次调查的净开销 | 约 85,000 个令牌,约 6 轮 | 约 3,000 个令牌,约 2 轮 |
每次调查的成本约为 $0.40–$1.20,具体取决于模型(Claude Opus / Sonnet / Haiku)。成本会随着文件大小和调查深度线性增长。
开发者时间
由开发者测量的同一项调查:
| 步骤 | 不使用 MCP | 使用 memorydetective |
|---|---|---|
捕获内存图并运行 leaks | 5 分钟 | 5 分钟(相同) |
阅读并解读 leaks 文本转储 | 15–30 分钟(浏览 200 KB 的重复堆栈帧) | 30 秒(阅读 3 KB 摘要) |
| 找出问题模式 | 10–20 分钟(凭经验识别循环形态) | 即时(分类器返回 patternId + 修复提示) |
| 在源码中定位可疑类型 | 10–15 分钟(使用 grep 并手动导航) | 30 秒(swiftGetSymbolDefinition 返回 file:line) |
| 找出每个调用点,评估修复的影响范围 | 5–10 分钟(Xcode / grep) | 10 秒(swiftFindSymbolReferences) |
| 总耗时 | 45–80 分钟 | 约 10 分钟 |
这些数字根据一次匿名的真实调查取整得出(SwiftUI 中带标签的 ForEach 存在循环引用,固定保留了约 28 MB 的网络栈状态)。实际耗时会因循环的复杂程度和代码库大小而异。
收益微乎其微时
请如实说明它在哪些情况下帮助不大:
- 极小的内存图(单个环,原始大小 < 50 KB):与直接读取相比,MCP 的开销大致抵消了节省的 token。开发时间方面仍有收益(无需手动解析环),但 token 方面的收益会缩小。
- 没有关联泄漏的一次性符号查找:直接用
grep即可,不需要这个工具。 - 首次调查新的代码库:无论是否使用 MCP,Agent 仍需要几轮来熟悉代码库。累积收益要到 Agent 缓存了项目结构后,在第二次及后续调查中才会显现。
收益会随着**(a)文件大小、(b)调查深度(多轮),以及(c)**每季度调查的泄漏数量而累积。对于每年修复一次泄漏的单个开发者,价值主要体现在节省开发时间。对于在每个 PR 中运行 verifyFix 检查的团队,token 和时间方面的节省会在数百次运行中累积。
配置
memorydetective 二进制程序通过 stdio 使用 MCP 通信。将任意兼容 MCP 的客户端指向它即可。
Claude Code
// ~/.claude/settings.json (global) or .mcp.json (per-project)
{
"mcpServers": {
"memorydetective": { "command": "memorydetective" }
}
}
Claude Desktop
// ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"memorydetective": { "command": "memorydetective" }
}
}
编辑后重启 Claude Desktop。
Cursor
// ~/.cursor/mcp.json
{
"mcpServers": {
"memorydetective": { "command": "memorydetective" }
}
}
Cline (VS Code)
// VS Code settings.json
{
"cline.mcpServers": {
"memorydetective": { "command": "memorydetective" }
}
}
Kiro
Kiro 通过全局配置支持 MCP 服务。配置块与 Claude Desktop 的相同:
{
"mcpServers": {
"memorydetective": { "command": "memorydetective" }
}
}
请查阅 Kiro 的 MCP 设置文档,了解系统上的确切配置文件路径。
GitHub Copilot(实验性)
GitHub Copilot 在 Agent 模式下支持 MCP 服务(VS Code 1.94+)。将以下内容添加到仓库中的 .vscode/mcp.json:
{
"servers": {
"memorydetective": {
"type": "stdio",
"command": "memorydetective"
}
}
}
Copilot 的 MCP 集成更新很快。如果此代码片段已过时,请参阅 VS Code MCP 文档。
下方每个布尔型 MEMORYDETECTIVE_* 标志都接受 strtobool 真值集合(不区分大小写):1 / true / t / yes / y / on(真)和 0 / false / f / no / n / off(假)。无法识别的值会针对每个变量输出一次 stderr 警告,并回退到文档说明的默认值。v1.17 之前,解析器仅接受 1,这会导致运维人员导出 =true 或 =yes 时静默无效。此提示警告受 MEMORYDETECTIVE_SUPPRESS_PLATFORM_ADVISORY 控制。
| 变量 | 默认值 | 作用 |
|---|---|---|
MEMORYDETECTIVE_REDACTION | balanced | 对每个工具响应应用输出脱敏。balanced 会将主目录路径缩写为 ~/...,并遮盖类似令牌的机密信息(AWS 密钥、GitHub PAT、Stripe、Slack、Bearer 身份验证)。strict 还会遮盖主机名、IPv4 地址和 bundle 标识符。off 会关闭脱敏(适用于仅限本地的调试)。服务器启动时会记录一次模式。 |
MEMORYDETECTIVE_ALLOW_LAUNCH | 未设置 | 布尔值(strtobool)。允许使用 bootAndLaunchForLeakInvestigation。该工具会针对调用方提供的路径和 bundle ID 执行 xcodebuild 和 xcrun simctl launch,因此必须选择启用。未启用时,该工具会返回 ok: false 和 state: launchNotAllowed,并附上清晰说明。仅当你信任 Agent 生成的输入时才设置此项。 |
MEMORYDETECTIVE_MAX_RECORDING_SECONDS | 300 | 对 recordTimeProfile.durationSec 的上限。超过上限的请求会被拒绝,并附上清晰错误信息。内部限制为 3600s(1h)的硬上限,避免配置错误的环境变量导致限制失效。 |
MEMORYDETECTIVE_TRACE_ROOT | ~/Library/Application Support/memorydetective/traces | 当 recordTimeProfile.output 是相对路径时使用的目录。对于 v1.8 向后兼容,绝对路径会绕过此默认值。该目录也是 cleanupTraces 的默认扫描路径。首次写入时会自动创建目录。 |
MEMORYDETECTIVE_ALLOW_EXTERNAL_CLEANUP | 未设置 | 布尔值(strtobool)。允许 cleanupTraces 扫描并删除 MEMORYDETECTIVE_TRACE_ROOT 之外的 .trace bundle。未启用时,解析为配置根目录之外的请求会返回 ok: false 和失败原因,且不会删除任何内容。默认禁止在配置边界之外执行破坏性磁盘操作。 |
MEMORYDETECTIVE_SUPPRESS_PLATFORM_ADVISORY | 未设置 | 布尔值(strtobool)。关闭 captureMemgraph、captureScenarioState 和 bootAndLaunchForLeakInvestigation 首次使用时发出的 macOS 26.x 平台提示。还会关闭 v1.17 在无法识别布尔值(任何 MEMORYDETECTIVE_* 标志)以及 schemaDiscovery TOC 获取失败时输出的 stderr 警告。如果你已安装 iOS 18 模拟器运行时且不需要提醒,此项会很有用。 |
MEMORYDETECTIVE_AUTO_OPEN_INSTRUMENTS | 未设置 | 布尔值(strtobool)。当 xctrace 超时(macOS 26.x 回归问题)时,让 recordTimeProfile 调用 open -a Instruments <tracePath>,作为无需等待结果的备用方案。v1.17 增加了打开前的 MANIFEST.plist 可用性检查,因此自动打开流程会跳过卡住的 52K 存根 bundle(否则会在 Instruments.app 中弹出 “Document Missing Template Error” 对话框)。响应中的 openedInInstrumentsApp 字段会报告是否已调用打开操作;bundleStatus(v1.17)会报告磁盘上的 bundle 是否为 unknown / salvageable / wedged。 |
MEMORYDETECTIVE_PREFLIGHT_XCTRACE | 未设置(自动) | 布尔值(strtobool)+ auto。控制 recordTimeProfile 中的预检,该检查可在约 3-5 秒内检测 macOS 26.x 的 xctrace 卡死问题,避免等待用户设置的完整 durationSec 加 30s 宽限时间。真值会强制启用,无论平台或目标为何。假值会强制关闭。未设置时,预检会在 macOS 26.x 模拟器附加(已知有问题的组合)时自动启用,在其他情况下保持关闭。为避免重复启动应用,--launch 模式下会跳过预检。自动启用的副作用:完整录制开始前会先运行 2 秒预检。 |
API
42 个 MCP 工具 + 34 个资源 + 7 个提示词,按用途分组。工具描述带有类别前缀([mg.memory]、[mg.trace]、[mg.build]、[mg.scenario]、[mg.code]、[mg.log]、[mg.render]、[mg.ci]、[mg.discover]、[ops]、[meta]),便于一眼看出相关工具。
许多工具的响应中都包含 suggestedNextCalls 字段。这是一个经过类型化的 { tool, args, why } 条目列表,已根据当前结果预先填充,因此编排用的大模型无需重新推理即可串联调用。请从 getInvestigationPlaybook(kind) 开始,以获取规范的调用顺序。也可以在任何支持 MCP 斜杠命令的客户端中输入 /investigate-leak(提示词之一)。
周期分类器包含 36 种已命名的反模式,涵盖 SwiftUI(包括 Swift 6 / @Observable / SwiftData / NavigationStack 时代,以及 v1.9 的 swiftui.observable-write-on-every-render 形态)、Combine、Swift 并发(包括基于 self 的 AsyncSequence 和新的 Observations API)、UIKit(Timer/CADisplayLink/UIGestureRecognizer/KVO/URLSession/WebKit/DispatchSource,以及 v1.9 的 uikit.viewcontroller-retained-after-pop 形态)、Core Animation、Core Data、Coordinator 模式,以及常见的第三方库 RxSwift + Realm。每种模式都包含:
- 一条文本形式的单行
fixHint - 一个置信度等级(
high/medium/low) - 一个
staticAnalysisHint,指向可补充运行时证据的 SwiftLint 规则(如果没有对应规则,则明确说明此缺口。凸显了差异化优势:memorydetective 能发现解析时 linter 遗漏的问题) - 一个
fixTemplate,包含具体的 Swift 修改前/修改后代码片段(v1.7 新增),Agent 可通过 SourceKit-LSP 源码桥接工具直接调整,以适配用户的代码
读取与分析(14)
以下所有 9 个跟踪侧分析器都接受可选的第二个参数
AnalyzeTraceOptions(v1.18 D-02)。当由summarizeTrace调用时(它会预先运行一次架构发现),缓存会被转发,因此会跳过每个分析器对xctrace --toc的调用。直接调用时不设置此选项,行为与 v1.17 完全相同。 | 工具 | 说明 | |---|---| |analyzeMemgraph| 对.memgraph运行leaks并返回摘要(总计、ROOT CYCLE 块、通俗易懂的诊断)。 | |findCycles| 仅提取 ROOT CYCLE 块并将其展平为链,支持可选的className子字符串筛选。 | |findRetainers| “是谁让<class>保持存活?”返回从顶层节点到匹配项的保留链路径。 | |countAlive| 按类统计实例数量。提供className可查询单个数量;省略则返回泄漏最多的前 N 个类。v1.17:可配置噪声筛选器(excludeFrameworkNoise、additionalNoisePatterns、unsuppressClassPatterns、noiseAuditMode),以便根据每个应用调整可操作视图。可变大小类会报告instanceSizeBytesMin / Max / Median(v1.17 之前报告首次观测到的值)。 | |reachableFromCycle| 按循环范围统计可达性。“从以<Y>为根的循环中可以访问到多少个<X>实例?”区分实际元凶与其保留的依赖项。 | |diffMemgraphs| 比较两个.memgraph快照:总量差异、类数量变化,以及新增/消失/持续存在的循环。 | |analyzeAbandonedMemory| 比较两个.memgraph快照中的堆引用树类数量(而非循环列表),并将每个数量增长的类归类为kvo-observer-orphaned、notificationcenter-observer-leaked、cache-too-aggressive、singleton-retains-payload或unknown-growth。揭示leaks(1)会报告为leakCount: 0的这类错误,因为不存在严格循环。v1.10 新增actionableGrowth[]和actionableShrinkage[](过滤框架噪声的视图),并支持outputFormat: "verify-fix-table",可直接输出精简的 Class | Before | After | Delta Markdown 表格。 | |verifyFix| 基于循环语义进行差异比较:针对每种模式给出 PASS/PARTIAL/FAIL 判定及释放的字节数。可用于 CI 门禁。expectedAliveClasses白名单(v1.14)可排除单例/缓存/由 OS 保留的窗口,使其不会导致 FAIL;v1.17 将每个条目扩展为按模式匹配({ pattern, mode: "exact" \| "substring" \| "regex" }),裸字符串仍默认采用子字符串匹配。 | |classifyCycle| 将每个 ROOT CYCLE 与内置的 36 种已命名反模式目录匹配(SwiftUI / Combine / Concurrency / UIKit / Core Animation / Core Data / Coordinator / RxSwift / Realm),并提供置信度、文本形式的fixHint、staticAnalysisHint(说明适用的 SwiftLint 规则,或明确指出缺口),以及fixTemplate(Swift 修复前后代码片段)。 | |analyzeHangs| 解析xctrace的potential-hangs架构;返回 Hang 和 Microhang 数量及耗时最长的前 N 项。传入topFramesByHangStartNs(通常来自串联的analyzeTimeProfile关联分析),可通过mainThreadViolations[]为每个最长挂起项补充信息,将阻塞原因归类为sync-io、db-lock、network或lock-contention。 | |analyzeAnimationHitches| 解析xctrace的animation-hitches架构;按类型报告数量,以及超过 Apple 认定的用户可感知 100ms 阈值的卡顿数量。 | |analyzeTimeProfile| 解析xctrace的time-profile架构;按样本数量返回排名靠前的符号。当 xctrace 无法解析符号时,报告 SIGSEGV 并提供规避方法。 | |analyzeAllocations| 解析xctrace的allocations架构;返回按类别汇总的数据(累计字节数、分配数量、生命周期 = transient/persistent/mixed)以及主要分配器。 | |analyzeAppLaunch| 解析xctrace的app-launch架构;返回冷/热启动类型及各阶段细分(process-creation、dyld-init、ObjC-init、AppDelegate、first-frame)。 | |logShow| 使用log show --style compact一次性查询 macOS 统一日志,并按谓词/进程/子系统筛选。返回解析后的条目(时间戳、类型、进程、子系统、类别、消息)。 |
捕获 / 记录(4)
| 工具 | 说明 | 模拟器 | 设备 |
|---|---|---|---|
recordTimeProfile | 封装 xcrun xctrace record --template "Time Profiler" --attach ... --time-limit Ns --output ...。返回 bundleStatus: "unknown" | "salvageable" | "wedged"(v1.17),以便调用方在超时后根据磁盘上的实际情况进行分支处理,而不是盲目相信 tracePath。自动打开路径(MEMORYDETECTIVE_AUTO_OPEN_INSTRUMENTS)会在启动 Instruments.app 前检查 MANIFEST.plist,以跳过损坏的 52K 占位文件。 | ✅ | ✅ |
recordViaInstrumentsApp | macOS 26.x 的备用方案(v1.16)。通过 open -a Instruments 打开 Instruments.app,返回 instructions[] 数组,告知用户应选择哪个模板,以及何时点击 Record / Stop / Save;随后每 5 秒轮询一次 watchDir,查找新的 .trace 包(修改时间稳定 10 秒)。v1.17:每次轮询时还会通过 AppleScript 查询正在运行的 Instruments.app,以查找 watchDir 外保存的文档。匹配后会返回路径并设置 savedOutsideWatchDir: true,这样点击 Save 并接受 Desktop 默认位置的用户就不会再遇到超时。成功后会接续调用 inspectTrace。 | ✅ | ✅ |
captureMemgraph | 封装 leaks --outputGraph <path> <pid>。通过 pgrep -x 将 appName → pid。对于 macOS 26.x 上的 Failed to get DYLD info for task 回归问题,返回结构化的 workaroundNotice,其中包含稳定的问题 ID(minimal-corpse、permission-denied、leaks-not-found、transient),以及备用路径:使用 recordTimeProfile(Allocations)+ analyzeAllocations。 | ✅ | ❌。请使用 Xcode |
logStream | 在限定时长(≤ 60 秒)内封装 log stream --style compact。返回该时段内收集的解析后条目。 | 不适用 | 不适用 |
验证修复编排(3,v1.8)
这三个工具组合成一个确定性的验证修复循环:使用 MallocStackLogging=1 启动应用,以便 leaks 正常工作;驱动 UI 放大疑似泄漏;修复前拍摄快照;提交修复;修复后拍摄快照;然后运行 diffMemgraphs。
| 工具 | 说明 |
|---|---|
bootAndLaunchForLeakInvestigation | 一次调用即可完成构建 + 启动模拟器 + 安装 + 启动,并通过 SIMCTL_CHILD_* 传递 MallocStackLogging=1。解析模拟器(udid、名称+OS,或当前已启动的模拟器),通过 xcodebuild -showBuildSettings -json 查找 BUILT_PRODUCTS_DIR / WRAPPER_NAME / EXECUTABLE_NAME / PRODUCT_BUNDLE_IDENTIFIER,并返回主机 PID + UDID + Bundle ID,可直接接续调用 captureMemgraph。此工具不可或缺,因为 leaks --outputGraph 在 macOS 26.x 上出现回归,仅当目标应用启动时的环境中包含 malloc-stack-logging 才能正常工作。 |
replayScenario | 通过轻点 / 滑动 / 等待 / 输入操作驱动 iOS Simulator,并支持使用 repeat 次数放大仅在迭代 N 次后才显现的泄漏。轻点目标接受 label、elementId 或 coords。可选依赖 Cameron Cooke 的 axe CLI。 |
captureScenarioState | 用于验证修复的组合式快照:将 .memgraph + .png 截图 + .ui.json 辅助功能树写入 outputDir,并统一添加 label 前缀(通常为 before / after)。子捕获尽力而为:如果 leaks 在 macOS 26.x 上失败,截图和 UI 树仍会完成,并通过 memgraphWorkaroundNotice 提供 captureMemgraph 的 workaroundNotice。 |
发现(3)
| 工具 | 说明 |
|---|---|
listTraceDevices | 解析 xcrun xctrace list devices(设备 + 模拟器 + UDID)。 |
listTraceTemplates | 解析 xcrun xctrace list templates(标准模板 + 自定义模板)。 |
inspectTrace | 用于检查 .trace 包的导航工具。返回包含的架构 + 行数 + 设备 / OS / 模板元数据 + suggestedNextCalls[],将每个已填充的已知架构映射到相应分析工具。对任何 .trace 都应首先调用此工具。v1.11 新增。v1.17:具备容错能力;当 xctrace export --toc 在损坏的 52K 包上失败时,不会抛出异常,而是返回 ok: true、schemas: [] 和诊断字符串。 |
综合分析(1)
| 工具 | 说明 |
|---|---|
summarizeTrace | 一次调用即可串联 inspectTrace + 5 个分析器并行运行 + 交叉关联结果(例如,重叠的卡顿与掉帧等)+ 预先生成一张精简的(<10 KB)Markdown 摘要卡片,其中包含一句话标题、各区域的子部分和 suggestedNextCalls。这就是“一次调用即可从跟踪生成摘要卡片”的用法。需要一次综合分析,而不是手动串联 5–6 个分析器时,请使用此工具。v1.13 新增。v1.18 D-02:预先执行一次架构发现,并与全部 6 个分析器共享缓存,在真实 Apple 跟踪数据上可缩短 600–3000ms 的实际耗时。 |
生产环境诊断(1,v1.18)
| 工具 | 说明 |
|---|---|
analyzeMetricKitPayload | 导入来自真实设备 TestFlight / App Store 构建的 Apple MetricKit .mxdiagnostic JSON 载荷(目前没有其他 MCP 竞品覆盖此场景)。支持三种输入形式:payloadPath(单个文件)、payloadDir(汇总目录中的所有 .mxdiagnostic 文件)、payloadJson(内存中的原始数据)。包含三个输出部分:crashCluster[](按 exception-type / binary / top-frame 分组,每个条目包含 topFrame + affectedBuilds[] + 原始 binaryUUID + offset,供下游 dSYM 符号化使用)、hangHotspots[](按 hangDurationMs 排序,并解析本地化时长,例如 "5.4 sec" / "20秒" 等)、cpuExceptions[] + diskWriteExceptions[]。新增 4 个 SupportStatusKind 值。自动提供跨工具调用链提示(类似 objc_release 的顶部帧 → findCycles;libsqlite3 顶部帧 → 使用主线程违规分类器运行 analyzeHangs)。v1 不支持符号化;仅提供原始字节。模拟器不会生成 MetricKit 载荷(Apple 侧限制);此工具定位为事后分析器,而非实时采集工具。v1.18 新增。 |
渲染(1)
| 工具 | 说明 |
|---|---|
renderCycleGraph | 读取 .memgraph,选择一个根循环,并输出 Mermaid 图(可嵌入 Markdown)或 Graphviz DOT。应用级类以红色突出显示;循环回边终止符以琥珀色突出显示。 |
运维(1)
| 工具 | 说明 |
|---|---|
cleanupTraces | 预览并删除 MEMORYDETECTIVE_TRACE_ROOT 下的 .trace 包。默认 dryRun: true(Agent 必须主动选择删除)。操作在 .trace 边界处停止(不会深入包内)。外部根目录需要设置 MEMORYDETECTIVE_ALLOW_EXTERNAL_CLEANUP=1(默认拒绝)。在累积了数十到数百 MB 的跟踪数据后,可定期调用此工具清理若干次 recordTimeProfile 会话产生的数据。 |
CI / 测试集成(3)
| 工具 | 说明 |
|---|---|
detectLeaksInXCTest | 构建单元测试方案,使用可选的 -only-testing: 筛选条件运行测试,针对 xctest 运行器(或应用承载包的自定义 processName)捕获前后 .memgraph 基线并进行差异比较。当出现不在用户允许列表中的新根循环时,返回 passed: false。设置 outputHtmlPath 还可写入独立的 HTML 报告。可在 CI 中运行。 |
detectLeaksInXCUITest | XCUITest 对应工具:构建工作区,运行指定的 XCUITest,针对宿主应用捕获前后 .memgraph 基线并进行差异比较。当出现不在用户允许列表中的新根循环时,返回 passed: false。设置 outputHtmlPath 还可写入独立的 HTML 报告。可在 CI 中运行。 |
compareTracesByPattern | 跟踪数据侧对应于 verifyFix 的工具。针对某个性能类别(hangs、animation-hitches 或 app-launch)比较两个 .trace 包,并返回 PASS/PARTIAL/FAIL,以及前后统计数据和差值。应用阈值:最长卡顿低于 hangsMaxLongestMs 时,hangs 为 PASS;最长掉帧低于 hitchesMaxLongestMs 时,hitches 为 PASS(默认值为 100ms,即 Apple 认定的用户可感知阈值);总时长低于 appLaunchMaxTotalMs 时,app-launch 为 PASS(默认值为 1000ms)。 |
5 分钟内将 memorydetective 加入 CI
detectLeaksInXCTest + outputHtmlPath 是为每个 PR 设置泄漏门禁的基础。下面的任务会在每次推送和 PR 时运行指定的单元测试方案,将 HTML 报告上传为工作流构件,并在允许列表之外出现新的 ROOT CYCLE 时失败。将此文件复制到 .github/workflows/leaks.yml,并调整 workspace、scheme 和测试标识符:
name: leaks
on: [push, pull_request]
jobs:
detect-leaks:
runs-on: macos-14
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- run: sudo xcode-select -s /Applications/Xcode_15.4.app
- run: npm install -g memorydetective
- run: |
xcrun simctl boot "iPhone 15" || true
xcrun simctl bootstatus "iPhone 15" -b
- run: |
cat > leaks.json <<EOF
{
"workspace": "DemoApp.xcworkspace",
"scheme": "DemoAppTests",
"destination": "platform=iOS Simulator,name=iPhone 15,OS=18.0",
"testCaseFilter": "DemoTests/LeakSensitiveCase",
"outputHtmlPath": "${GITHUB_WORKSPACE}/leak-report.html",
"allowlistPatterns": ["SwiftUI", "_TtC"]
}
EOF
memorydetective tool detectLeaksInXCTest --input leaks.json
- if: always()
uses: actions/upload-artifact@v4
with:
name: leak-report
path: leak-report.html
retention-days: 14
如果想原样复制,同一文件也位于 examples/ci/github-actions-leaks.yml。注意:
- **模拟器运行时:**在
macos-14运行器上固定使用 iOS 18。macOS 26.x 内核回归问题(task_for_pid)会导致leaks无法检查 iOS 26 模拟器;iOS 18 是标准的规避方案(参见上方的亮点说明)。 - **允许列表模式:**与发生泄漏的 ROOT CYCLE 根类匹配的子字符串。处理积压问题时,可用它们屏蔽已知的存量泄漏。
_TtC可匹配 Swift 混淆类名前缀,这些前缀偶尔会出现在 SwiftUI 内部实现中。 - **HTML 构件:**报告自包含(CSS 内嵌,无外部资源),因此 PR 评论机器人和评审者可直接通过构件 URL 预览。
- **构建缓存:**添加以
Package.resolved+*.xcconfig为键的actions/cache@v4,以跳过不同运行之间的build-for-testing重建。随后,在同一任务中连续调用多个detectLeaksInXCTest时,在第二次调用中传入--skipBuild。
Swift 源码桥接(5)
将内存图诊断与通过 SourceKit-LSP 查找源代码相结合,打通“发现此循环中的泄漏 → 在项目中找到文件和行号”的流程。
| 工具 | 说明 |
|---|---|
swiftGetSymbolDefinition | 定位 Swift 符号声明所在的文件和行号。先用快速正则预扫描 candidatePaths(或 hint.filePath),然后让 SourceKit-LSP 执行跳转到定义。 |
swiftFindSymbolReferences | 通过 SourceKit-LSP 的 textDocument/references 查找 Swift 符号的所有引用。跨文件查找需要 IndexStoreDB。索引缺失时,响应会附带 needsIndex 提示。 |
swiftGetSymbolsOverview | 通过 documentSymbol 列出 Swift 文件中的顶层符号(类、结构体、枚举、协议和自由函数)。当 Agent 进入新文件时,可快速了解文件内容。 |
swiftGetHoverInfo | 获取指定(行、字符)位置的类型信息和文档。用于区分 self 捕获:闭包中的类类型 self 可能导致泄漏;结构体类型的 self 则不会。 |
swiftSearchPattern | 对 Swift 文件执行纯正则搜索(无需 LSP 或索引)。可捕获 LSP 遗漏的内容:闭包捕获列表、Task { ... self ... } 代码块,以及根据泄漏链自定义的模式。 |
这些工具需要 macOS 和 Xcode(完整的 Xcode,而不只是 Command Line Tools。必须可以使用 xcrun sourcekit-lsp)。它们会为每个项目根目录启动一个 sourcekit-lsp 子进程,并在多次调用间复用;子进程空闲 5 分钟后关闭。
为什么
captureMemgraph无法用于实体 iOS 设备:leaks(1)只能附加到本地 Mac 上运行的进程(包括 iOS 模拟器)。从真实设备捕获 Memory Graph 需要通过 USB/lockdownd 使用 Xcode 调试器。这是不同的机制,没有对应的公开命令行工具。
资源(34)
循环模式目录也作为 MCP 资源提供,可通过 memorydetective://patterns/{patternId} 浏览。每项资源都是一段 Markdown 正文,包含模式名称、更详细的描述和修复提示。使用此方式可让 Agent(或使用支持 UI 的 MCP 客户端的人)浏览目录,而无需消耗一次 classifyCycle 调用。
memorydetective://patterns/swiftui.tag-index-projection
memorydetective://patterns/concurrency.async-sequence-on-self
memorydetective://patterns/webkit.wkscriptmessagehandler-bridge
memorydetective://patterns/swiftdata.modelcontext-actor-cycle
…
resources/list 会返回全部 34 个条目。resources/read 会将任何 memorydetective://patterns/{id} URI 解析为对应的 Markdown 正文。
提示词(7)
调查手册以 MCP 提示词的形式提供(在支持提示词的客户端中作为斜杠命令使用,例如 Claude Code)。
| 斜杠命令 | 功能 | 参数 |
|---|---|---|
/investigate-leak | 执行标准的 6 步 memgraph-leak 调查:analyzeMemgraph → classifyCycle → reachableFromCycle → swiftSearchPattern → swiftGetSymbolDefinition → swiftFindSymbolReferences。 | memgraphPath |
/investigate-hangs | 根据 .trace 诊断用户可感知的主线程卡顿。 | tracePath |
/investigate-jank | 根据 .trace 诊断丢帧/动画卡顿。 | tracePath |
/investigate-launch | 根据 .trace 诊断冷启动/热启动缓慢。 | tracePath |
/verify-cycle-fix | 对比修复前后的 .memgraph 快照,确认修复已生效。 | before、after |
/summarize-trace | 对 .trace 进行跨架构的一次调用摘要。封装 summarizeTrace。v1.13+。 | tracePath |
/investigate-metrickit | 对来自 TestFlight/App Store 构建的 Apple MetricKit .mxdiagnostic 载荷进行事后分析。封装 analyzeMetricKitPayload,并按优先级读取 crashCluster + hangHotspots + cpuExceptions + diskWriteExceptions,同时提供跨工具链提示(objc_release → findCycles、sqlite → analyzeHangs)。v1.18+。 | payloadPath |
每个提示词都会将用户提供的值填入标准调查手册的参数模板,然后向 Agent 提供可直接执行的简报。它调用的工具与读取和分析中列出的相同。提示词是编排捷径,并非独立引擎。
CLI 模式
同一个二进制文件也可作为精简 CLI,用于脚本和 CI:
memorydetective analyze <path-to-.memgraph> # totals, ROOT CYCLEs, diagnosis
memorydetective classify <path-to-.memgraph> # match patterns + render fix hint
memorydetective tool <toolName> --input <json> # generic dispatcher for any MCP tool
memorydetective --help
memorydetective --version
不带参数调用时,二进制文件会通过 stdio 作为 MCP 服务启动。
tool 子命令可按名称调用任何已注册的 MCP 工具,并从 JSON 文件读取输入。当工具返回 ok && passed !== false 时,退出码为 0;否则为 1,因此可以无缝用于 CI 门禁。目前支持的工具名称:detectLeaksInXCTest、detectLeaksInXCUITest(上文的 CI 配置使用了这些工具)。
要求
- 安装了 Xcode Command Line Tools 的 macOS(
xcode-select --install) - Node.js ≥ 20
开发
git clone https://github.com/carloshpdoc/memorydetective
cd memorydetective
npm install
npm test # 758 unit tests
npm run build # build → dist/
npm run dev # tsx, stdio mode (dev mode)
./scripts/demo.sh # full demo against a real .memgraph (set MEMGRAPH=path)
贡献
欢迎贡献。无论是 Bug 报告、功能请求还是新的循环模式,我们都欢迎。
- Bug/功能请求:提交 issue。
- PR:fork → branch →
npm install→ 修改代码 →npm test(758 项测试必须全部通过)→ 提交 PR,并简要说明所做的更改及原因。
向 classifyCycle 添加循环模式
classifyCycle 内置了 36 种模式,涵盖 SwiftUI(包括 Swift 6/@Observable/SwiftData/NavigationStack/v1.9 中的 observable-write-on-every-render 和 viewcontroller-retained-after-pop 形态)、Combine、Swift Concurrency(包括 AsyncSequence-on-self 和 Observations)、UIKit(Timer/CADisplayLink/UIGestureRecognizer/KVO/URLSession/WebKit/DispatchSource)、Core Animation、Core Data、Coordinator 模式、RxSwift 和 Realm。添加新模式的步骤如下:
- 编辑
src/tools/classifyCycle.ts。在PATTERNS中添加一个条目,包含id、name、fixHint和match函数。 - 在
src/tools/readTools.test.ts中添加测试,断言新模式能匹配一个具有代表性的 memgraph fixture。 - 在
src/runtime/staticAnalysisHints.ts中添加staticAnalysisHint条目(该文件中的测试会确保它与PATTERNS一一对应)。 - 在
src/runtime/fixTemplates.ts中添加fixTemplate条目(同样会检查一一对应关系)。 - 提交 PR。
支持本项目
如果 memorydetective 为你节省了时间,你可以支持项目的持续开发:
- ☕ 请我喝杯咖啡
- 💖 在 GitHub 上赞助
每一份支持都有助于维护和完善文档。
许可证
Apache 2.0。请参阅 LICENSE 和 NOTICE。
允许商用、修改、分发和专利使用。通过 NOTICE 文件包含署名条款。
为什么叫“memorydetective”?
在 SwiftUI 中追查循环引用就像侦探办案:你有一具尸体(泄漏的实例)、一个犯罪现场(.memgraph)和一串嫌疑人(引用链)。该工具帮助你解读证据并找出凶手。品牌名称源于这项工作。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。