外观
Memory Contract 技术演进与实验:从单一数字到五指标契约
2026-10-26 · 五指标以外,还要核新来源和参考窗口
本月物理/驻留/虚拟内存历史验收沿用,Free与Available分别取得限定场景五轮证据;这不使五个数字可互换,也不升级为全部系统版本精度保证。
问题表现:值不变时无法仅凭曲线判断是负载稳定还是旧缓存;Free不足以代替Available;参考API读点与产品源窗口不同也会制造“误差”。
实验所得:Free五轮与Available各自场景、组成包络和来源一次发表独立核对。Available的自有host_statistics64组件包络是候选异常对照,secluded完整性与私有字段同义仍未证,不能把包络相容称物理校准。Free阶段验收 · Available方案及结果。原来按更快配置请求不一定得到更快源,曾实测约半秒节拍;配置值不能替代实际窗口统计。源节拍调查。
判断与避免:同一目标生命、完整字段schema、原生时窗和每源唯一发表逐项核;独立读取区间只给上下界,不选中点作真值;参考过宽明确不可评估。进程footprint、resident、virtual与device available/free按scope分开,单位bytes→MiB用2^20,不能把虚拟地址空间的大数解释为实际RAM占用。适用于当前已测设备/版本;旧无标记Session按旧算法回放,不回写新公式。
本节E1复盘,不新增E4;实验方法索引提供跨指标对照步骤。
1. 当前结论先放前面
- 当前产品内存口径是
memory-contract.v2:五个独立指标(Physical Footprint、Real Memory、Virtual Memory、Available Memory、Free Memory),彼此 scope、语义、证据状态都不同,不能相互替代。 - 历史上
Xcode Memory与Physical Footprint是同一底层字段physFootprint的重复产品命名;Resident Memory与Real Memory是同一底层字段memResidentSize的重复产品命名——memory-contract.v2把这两组重复合并为单一产品指标,旧名只保留兼容语义。 - 历史上
Available Memory的公式其实只计算了vmFreeCount × pageSize(即今天的 Free Memory),并不是 XNU 官方memorystatus_available_pages语义;memory-contract.v2把两者正式分离,新的 Available 是仍处于candidate状态的 XNU 语义候选重建。
2. 最初工程问题
早期版本需要快速验证"能否无侵入读取目标 App 内存占用",选择直接透传 sysmontap 返回的若干内存相关字段,并沿用了当时看起来直观的命名(Xcode Memory、Resident Memory、Available Memory)。
3. 第一代方案与为什么当时合理
直接暴露 sysmontap 原始字段并按字面含义命名,是验证链路可用性阶段的合理选择——能最快证明"Perfowl 可以无侵入读到内存数据",不需要等待完整的语义研究。
4. 暴露出的真实问题
- 同一字段被重复命名为两个"不同"指标:
physFootprint同时被展示为Xcode Memory和Physical Footprint;memResidentSize同时被展示为Resident Memory和Real Memory。这不是两套独立的采集能力,而是产品层的命名重复,容易让使用者误以为存在两个独立数据源可以相互印证。 - "Available Memory" 名不副实:旧版把
vmFreeCount × pageSize命名为Available Memory,但这个公式只计算了完全空闲页,并不是 XNU 官方语境下"系统认为可以较快投入使用的页面"(还应包含 external/purgeable 等可回收页)。命名与实际语义不符,容易让使用者高估系统真实可用的内存余量。 - 固定 OOM 阈值缺乏依据:早期文档存在按机型 RAM 大小硬编码 Jetsam 红线的表述,但真实终止阈值受系统版本、设备状态、进程优先级、entitlement 与动态内存压力共同影响,固定数字容易产生误导性结论。
5. 候选方案:memory-contract.v2 五指标拆分(已采纳)
- 假设:把内存语义按"物理占用/驻留映射/地址空间/设备空闲/设备可用"五个不同维度拆开,比维持"内存"这一模糊单数概念更能支撑准确诊断。
- 方案(
FTI-002开发方案,2026-09-16 批准):- 产品层收敛为五个独立指标,metricID/scope/公式与知识 Canonical 页保持逐项一致;
vmFreeCount × pageSize正式更名为Free Memory(ios.device.memory.free);- 新增
Available Memory(ios.device.memory.available)作为 XNU memorystatus 语义的候选重建,公式为(vmFreeCount + vmExtPageCount + vmPurgeableCount) × pageSize,四项必要字段任一缺失即整体missing,不退化为 Free 的数值; - 历史 Session 中的
availableMemoryBytes字段做只读迁移:旧memoryContractVersion下按legacy-free-mislabeled解释为 Free,不与新 Available 语义混淆,历史文件本身不回改; - 移除固定机型 OOM 红线表述,改为"同设备、同系统、同场景"的相对回归方法论。
- 判定:采纳,是当前 Registry 与知识库的标准口径。
6. 被证伪路线与停止条件
未发现独立于 memory-contract.v2 方案之外、被系统性实验后又放弃的内存采集路线(不同于 Startup 领域的多次源切换)。当前内存领域的核心工程问题主要是语义澄清与命名纠正,不是采集通道本身的技术路线之争——sysmontap 从项目早期至今一直是内存字段的唯一事实源。
7. 最终方案为什么胜出
五指标拆分方案胜出,原因:
- 消除了"两个不同名字实际是同一底层字段"的重复认知负担;
- 用准确的命名(Free vs Available)避免了把"完全空闲页"误当作"系统认为可用的全部余量";
- 用 fail-closed 的 Available 候选重建(四字段必须同时有效)避免了用不完整数据编造一个看似精确的可用内存数字;
- 历史 Session 只读迁移策略保证了新旧口径切换不会静默篡改已发布的历史证据。
8. 从 POC 到产品化又踩了什么坑
CORE-8(2026-09-05):新增确定性RawMetricEngine,五类内存语义在这一批次独立落地(Memory、XcodeMemory candidate alias、Real、Virtual、Available),并明确"没有同场或真机证据的项未升级为数值 validated"。FTI-002方案(2026-09-16):把知识库、Registry、Collector、Session schema、历史兼容、Export/Report 与 Workbench 统一到同一个版本化契约memory-contract.v2,并把知识 Canonical 页列为产品代码修改前必须对齐的事实源——公式变化必须先更新知识页,再更新代码与测试。截至当前 devlog 整理,尚未发现该方案对应的独立result/validation批次文档;本页据此不对"该契约已完成端到端真机验收"做超出现有证据的断言。
9. 当前仍未关闭的门禁
Available Memory的字段语义验证(尤其secludedOverTarget是否可靠取得)与 PerfDog 同窗 E4 校准均未完成,definitionVersion停留在candidate.v1。Real Memory与 PerfDog "Real Memory" 的算法等价性尚未完成同窗 E4 校准。- 16 KiB page size 仍是候选架构约束值,不是当前 payload 的设备实测证据。
memory-contract.v2方案本身尚未见到对应的独立真机验收结果批次;现有真机证据依附于跨指标联合采集会话(如CORE-8的 E2 产品链验证),不构成契约级的专项 E4 闭环。
10. 可复用工程经验
- 发现"同一字段两个名字"时应该合并而不是各自维护:Xcode Memory/Footprint 与 Resident/Real 的重复命名教训说明,产品指标命名前应先确认底层字段是否已有其他名字在用。
- 命名要匹配官方语义,而不是匹配"听起来像":把
vmFreeCount × pageSize叫作 Available 是一个典型的"名不副实"案例,纠正后用更保守但准确的 Free 命名,同时给真正的 Available 语义留出候选重建的空间。 - fail-closed 优于凑合输出:Available 的四字段必须同时有效才计算,缺一即
missing,避免了用不完整证据伪造一个看似精确的数字。 - 旧数据迁移要保留可追溯的质量标签:历史
availableMemoryBytes不是简单改名,而是显式标注legacy-free-mislabeled迁移语义,保证历史 Session 仍可正确解释。
11. 原始 devlog 索引
p2-collector-core-core8-metric-engine.md:五类内存语义的 RawMetricEngine 首次落地。p2-memory-contract-v2-repair-plan.md:memory-contract.v2完整开发方案(对应内部问题追踪 FTI-002;本方案文档为approved · E1,尚无独立 result 批次)。
完整正文见 site/devlog/index.md 时间线或对应 /archive/ 归档页。
12. 延伸阅读
版本历史补记
| 日期 | 修订 | 来源 |
|---|---|---|
| 2026-10-26 | 补本月实验结论、失败路线与适用限制;早期阶段数字保留 | 月度梳理 |