iOS Memgraph Leaks 是一个用于证明和定位 iOS 内存泄漏的技能,可从运行中的模拟器进程或已有的 .memgraph 文件入手。当任务还需要模拟器构建、安装、启动、UI 驱动、日志或截图时,可搭配 ../ios-debugger-agent/SKILL.md 使用。
核心工作流
- 构建、启动并驱动那个应当释放对象的精确流程。
- 用 scripts/capture_sim_memgraph.sh 从运行中的模拟器进程采集内存图。
- 用 scripts/summarize_memgraph_leaks.py 汇总泄漏。
- 对每个应用自有的泄漏类型,用 leaks --traceTree=<address> <file.memgraph> 和分组泄漏证据检查所有权。
- 做最小的根因补丁,然后尽可能在同一模拟器上重新采集同一流程。
- 报告证据:修复前后的泄漏计数、消失的根类型、剩余泄漏、内存图路径以及测试/构建结果。
不要仅凭内存图变小就宣称修复了泄漏。可信的修复需要解释保持对象存活的所有权路径,并展示同一路径或类型在补丁后消失。
采集
优先从已用于复现的模拟器采集。解析模拟器 UDID 和应用 bundle 标识符,然后采集正在运行的应用:
SKILL_DIR="<absolute path to this loaded skill folder>" SIM="<simulator-udid>" BUNDLE_ID="<app.bundle.identifier>" MEMGRAPH_DIR="$(mktemp -d "${TMPDIR:-/tmp}/codex-ios-memgraph.XXXXXX")"
"$SKILL_DIR/scripts/capture_sim_memgraph.sh"
--udid "$SIM"
--bundle-id "$BUNDLE_ID"
--out-dir "$MEMGRAPH_DIR"
不要从目标应用仓库的 pwd 推导 SKILL_DIR;已安装的插件通常位于被调试应用之外。将采集结果存放在运行专用的临时目录或用户指定文件夹中,而不是 SKILL_DIR 下。
如果找不到进程,确认 bundle 标识符,并使用 xcrun simctl spawn "$SIM" launchctl list 检查正在运行的标签。
汇总
汇总已有的内存图:
"$SKILL_DIR/scripts/summarize_memgraph_leaks.py"
/path/to/app.memgraph
--trace-limit 5
--out /path/to/leak-summary.md
谨慎使用 --trace-limit。追踪树是有用的根因证据,但大型内存图可能产生嘈杂输出。如果追踪树显示 Found 0 roots referencing,将其视为不可达/自持有的泄漏候选,并使用汇总中的分组泄漏树或 leaks --groupByType <file.memgraph> 来识别被保留的字段和负载链。
根因规则
- 在泄漏输出或追踪中识别第一个应用自有的泄漏类型。
- 确定预期生命周期:进程、会话、账户、视图、请求或任务。
- 将惰性分配或延迟分配视为作用域缩减,而非泄漏修复,除非原本的急切分配本身违反了预期生命周期。
- 用 traceTree 所有权路径或隔离复现来证明循环引用主张。
- 对于不可达/自循环泄漏,traceTree 可能没有根路径;使用 leaks --groupByType 加源码验证来找到自持有边。
- 不要仅因总泄漏计数下降就宣称成功;要证明特定类型或路径消失。
- 将真正的根因分支与候选/噪声分支分开。
- 优先删除持有边,而不是添加宽泛的清理代码。
报告
一份有用的泄漏报告包括:
- 精确的流程和模拟器/应用构建
- 内存图和汇总路径
- 应用自有的泄漏类型和计数
- 至少一条所有权路径,或当对象从根不可达时的分组泄漏树证据
- 最小化的建议或已应用的持有边修复
- 修复后的前后证据
如果内存图只显示框架/运行时噪声,就如实说明,并建议下一次更窄范围的采集,而不是编造应用泄漏。