外观
iOS Memory 五指标拆分索引(兼容入口)
本页不再拥有 metric ownership。 从 2026-09-18 起,
memory-contract.v2的五个产品指标按语义拆分为五个独立 Canonical 页,公式、质量语义、证据与版本历史均以下面五页为准;本页只保留历史入口与拆分说明。
| 产品指标 | metricID | Scope | 新 Canonical 页 |
|---|---|---|---|
| Memory / Physical Footprint | ios.process.memory.physical_footprint | process | Physical Footprint |
| Real Memory | ios.process.memory.real | process | Real Memory |
| Virtual Memory | ios.process.memory.virtual | process | Virtual Memory |
| Available Memory | ios.device.memory.available | device | Available Memory |
| Free Memory | ios.device.memory.free | device | Free Memory |
领域总览见 iOS 内存拓扑总览,历史技术决策见 Memory Contract 技术演进与实验。
以下内容为拆分前 memory-contract.v2(v5,2026-09-15)沉淀的背景说明,继续保留供历史查阅,不代表当前权威口径;如与五个新 Canonical 页冲突,以新页为准。
Memory Contract:memory-contract.v2采集通道:DVT com.apple.instruments.server.services.sysmontap作用域:Memory / Real / Virtual 为 process;Available / Free 为 device当前证据状态:Memory / Real / Virtual / Free 可进入产品链;Available 仍是 candidate,未完成 PerfDog 同窗 E4 校准。
Perfowl 不再把“内存”压缩成一个含义模糊的数字。新产品契约只暴露五个独立指标;历史 Xcode Memory 与 Resident Memory 作为兼容/术语别名保留,不再重复占据实时卡片或新 Export。
一、五个产品指标
| 产品指标 | metricID | Scope | 原始字段 / 公式 | 当前语义 |
|---|---|---|---|---|
| Memory / Physical Footprint | ios.process.memory.physical_footprint | process | Processes[targetPID].physFootprint | App 的 physical footprint。Xcode Memory Gauge 使用 footprint 作为核心显示口径,但它不是“App 独占 RAM”或 Jetsam 的唯一判据。 |
| Real Memory | ios.process.memory.real | process | Processes[targetPID].memResidentSize | 当前以 resident size 映射为产品 Real Memory;与 PerfDog Real Memory 的算法等价性仍需同窗 E4。 |
| Virtual Memory | ios.process.memory.virtual | process | Processes[targetPID].memVirtualSize | 虚拟地址空间映射规模,不等于实际物理 RAM。数百 GiB 在 64 位进程上并不天然意味着采集错误。 |
| Available Memory | ios.device.memory.available | device | XNU memorystatus_available_pages 语义的 sysmontap 候选重建 | 设备级候选值;需要 free / external / purgeable 等组成项完整且语义受证据支持,否则保持 missing 。 |
| Free Memory | ios.device.memory.free | device | vmFreeCount × VMPageSizeBytes | 当前完全空闲的物理页容量。它有环境诊断价值,但 不等于 Available Memory。 |
二、为什么 Xcode Memory 与 Resident 不再单独展示
旧版 Registry 曾同时提供:
text
Physical Footprint ─┐
├─ physFootprint
Xcode Memory ───────┘
Resident Memory ────┐
├─ memResidentSize
Real Memory ─────────┘这两组分别来自完全相同的底层字段。memory-contract.v2 将产品层收敛为 Memory 与 Real Memory;旧 metricID 只用于读取历史 Session、旧 fixture 和 Raw Replay。Xcode 的对齐关系属于知识/校准语义,不代表第二套独立采集能力。
三、Memory / Physical Footprint 的正确边界
Physical Footprint 是分析 App 实际内存压力的重要指标,也是 Xcode 内存调试中重点观察的 footprint 口径。它通常更适合做版本回归、泄漏趋势和峰值比较,但不要把它描述成“完全独占且系统绝对无法回收的 RAM”,也不要把单个 Footprint 数字当成 Jetsam 的唯一输入。
Jetsam / memorystatus 会结合系统可用页、进程优先级、内存限制与其他内核状态做决策。正确的工程用法是:
- 用 Memory / Footprint 的趋势 判断目标 App 自身压力是否持续增加;
- 用 Available / Free 描述设备环境,而不是把设备级内存余量归因到目标 App;
- 真正发生终止时,以 Jetsam /
.ips等系统证据确认原因,不从单条曲线反推“必然 OOM”。
四、Real Memory 与 Virtual Memory
Real Memory
Perfowl 当前:
text
RealMemoryBytes = Processes[targetPID].memResidentSize
formulaVersion = resident-map.v1这是 resident-memory 映射。它可以包含当前驻留的 clean/file-backed 等页,因此与 footprint 的物理含义不同。新 UI 使用产品名 Real Memory,知识页明确其底层来源;在 PerfDog 同设备、同 App、同时间窗校准完成前保持候选对齐语义。
Virtual Memory
text
VirtualMemoryBytes = Processes[targetPID].memVirtualSize
formulaVersion = raw-gauge.v1Virtual Memory 描述虚拟地址空间映射规模。预留地址区间、映射文件、共享库等都会扩大这个数字,所以:
text
Memory = 200 MiB
Real = 250 MiB
Virtual = 300~500 GiB并不自相矛盾。Perfowl 底层始终保存 bytes;UI 数量级较大时改用 GiB 显示,不改写原始数据。
五、Free Memory:旧 Available 的真实语义
旧版 Perfowl 使用:
text
vmFreeCount × pageSize并把结果命名为 Available Memory。该公式只计算 free page list,因此从 memory-contract.v2 起正式更名为:
text
FreeMemoryBytes = vmFreeCount × VMPageSizeBytes
metricID = ios.device.memory.free
scope = device
formulaVersion = vm-free-pages.v1当前 Sidecar 在 iOS 15+ arm64 真机路径上仍使用 16 KiB 作为带来源标签的候选架构约束值,而不是宣称它来自本次 sysmontap payload 的设备实测字段。若未来得到可验证的设备 kernel page size,应升级 formulaVersion 与来源标签。
Free 很低不代表“整机只剩这么多能用”,更不代表目标 App 只剩这么多可分配预算;系统还可能存在可回收 file-backed / purgeable 等页。
六、Available Memory:XNU memorystatus candidate
Perfowl 的目标语义是 XNU 文档中 non-macOS memorystatus_available_pages 的可用页概念。当前候选映射为:
text
AvailablePagesCandidate =
vmFreeCount
+ vmExtPageCount
+ vmPurgeableCount
+ secludedOverTarget // 仅在能可靠取得并确认语义时加入
AvailableMemoryBytes = AvailablePagesCandidate × VMPageSizeBytes当前普通 sysmontap 路径尚未证明能够可靠取得 secludedOverTarget,所以第一阶段只允许:
text
(vmFreeCount + vmExtPageCount + vmPurgeableCount) × pageSize
quality = candidate-xnu-no-secluded前提是 free / ext / purgeable / pageSize 四项都真实存在。任一必要字段缺失时:
text
Available Memory = missing绝不退化为 Free Memory,也不补 0。
这条 Available candidate 只有完成字段语义验证和 PerfDog 同窗 E4 后,才允许提升证据状态。
七、Free 与 Available 的关系
text
Free pages ───────────────────┐
│
reclaimable external/file ───┼─→ Available candidate
purgeable pages ─────────────┤
secluded over target? ───────┘因此两者回答不同问题:
- Free:此刻完全空闲的页有多少;
- Available:在目标 memorystatus 语义下,系统认为可以较快投入使用的页有多少。
不要用 Free 替代 Available,也不要把 Available 当成目标 App 的 Jetsam headroom 或 memory limit。
八、历史 Session 兼容
memory-contract.v2 之前的 Session 没有独立 Free 字段;其 availableMemoryBytes 实际保存的是旧 vmFreeCount × pageSize。
新版读取历史 Session 时必须做只读迁移:
text
legacy availableMemoryBytes
↓
freeMemoryBytes
quality = legacy-free-mislabeled
new availableMemoryBytes
↓
missing
quality = missing-legacy-contract历史文件本身不改写,避免篡改原始证据。新 Session 显式写入:
text
memoryContractVersion = memory-contract.v2所以历史“Available”与新版 Available 不能直接拼成一条连续算法序列。
九、单位、缺失与质量规则
- Canonical unit:
bytes;UI 使用 MiB / GiB;MiB = bytes / 1024²、GiB = bytes / 1024³。 - 原始 bytes 不取整;UI 至少保留 1 位小数。
- 目标进程字段缺失、identity 未验证或设备组成项缺失时保持 missing / 对应 quality,绝不补 0。
Available的 candidate 质量必须可从 Session / Review / Export 恢复;不得只在实时 UI 留一个无法追溯的数字。
十、Memory Usage 产品交互
Workbench 使用一张 Memory Usage 卡片:
text
Memory Real Virtual
182.1 MiB 233.0 MiB 394.6 GiB
● ○ ○
Available Free
— 43.5 MiB
○ ○
[同一张趋势图]五个当前数值始终有位置;missing 显示 —。默认只绘制 Memory 曲线;点击 Real / Virtual / Available / Free 可在同一图表中增加或隐藏对应曲线,并支持多选。曲线显隐不改变底层采集。
十一、证据与已知限制
| 项目 | 当前结论 |
|---|---|
| 数据源 | DVT sysmontap,无侵入读取 |
| Memory | physFootprint;产品主指标 |
| Real | memResidentSize;PerfDog 等价性仍待 E4 |
| Virtual | memVirtualSize;地址空间语义 |
| Free | vmFreeCount × pageSize;已与旧 Available 语义分离 |
| Available | XNU memorystatus candidate;尚未完成字段探针与 PerfDog E4 |
| Page size | 当前 iOS 15+ arm64 16 KiB candidate 约束;非 payload 原样设备实测值 |
| Missing | 不补 0,不以 Free 冒充 Available |
| Evidence | Track A 可通过 E2 产品链验证;Available 在 E4 关闭前保持 candidate |
十二、技术溯源
- 系统服务 / 通道:
com.apple.instruments.server.services.sysmontap/ DTX;不修改被测 App。 - 采集调用:pymobiledevice3
Sysmontap.create(provider, interval=...);目标进程字段通过已验证 PID 投影,设备字段由同一 sysmontap System snapshot 读取。 - Apple Xcode Memory Gauge / footprint:Xcode 与 Instruments 的内存调试资料以 memory footprint 作为关键实际内存指标。
- XNU memorystatus 文档:
apple-oss-distributions/xnu/doc/vm/memorystatus.md描述 non-macOS available-pages 构成。
版本历史
| 版本 | 日期 | 修订要点 |
|---|---|---|
| v6(拆分,本页降级为索引) | 2026-09-18 | 本页不再拥有任何 metric ownership;五项指标拆分为独立 Canonical 页,公式与质量语义不再在本页维护。 |
| v5 | 2026-09-15 | 冻结 memory-contract.v2:产品层收敛为 Memory / Real / Virtual / Available / Free;旧 Available 迁移为 Free;Available 改为 XNU memorystatus candidate;移除 Xcode/Resident 重复产品语义;删除无证据固定 OOM 阈值与“唯一判据”表述。 |
| v4 | 2026-09-15 | 旧版性能测试实战页;其中把 Free pages 写作 Available、把 Footprint 描述成 Jetsam 唯一依据的内容已由 v5 纠正。 |
| v1 | 2026-09-04 | 首次发布内存多维指标定义。 |