Skip to main content

ohos-dev-distributed-mmi-ram-rom-measurement

Use when measuring RAM/ROM impact of OpenHarmony multimodal input (MMI) subsystem changes on DAYU200 (RK3568). Covers ROM measurement via readelf section analysis and file size comparison, RAM measurement via /proc/PID/smaps, smaps_rollup, hidumper --mem, and baseline/current .so swap methodology. Includes code-level theoretical analysis for heap-allocated data structures.

ソース情報

リポジトリ
openharmonyinsight/openharmony-skills
ソースの最終更新活動
2026年6月15日 03:20
検出された SKILL.md の言語
複数言語
スター
34
フォーク
7

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
6 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
ohos-dev-distributed-mmi-ram-rom-measurement
description
Use when measuring RAM/ROM impact of OpenHarmony multimodal input (MMI) subsystem changes on DAYU200 (RK3568). Covers ROM measurement via readelf section analysis and file size comparison, RAM measurement via /proc/PID/smaps, smaps_rollup, hidumper --mem, and baseline/current .so swap methodology. Includes code-level theoretical analysis for heap-allocated data structures.
metadata
{"author":"openharmony","scope":"domain","stage":"development","domain":"mmi","capability":"ram-rom-measurement","version":"0.2.0","status":"draft","tags":["multimodalinput","ram","rom","performance","binary-size"],"related-skills":["ohos-dev-distributed-mmi-device-test-harness"]}
# MMI RAM/ROM 影响度量 衡量 multimodalinput 子系统代码变更前后的 ROM(二进制体积)和 RAM(运行时内存)占用变化。 **前置 skill**: 编译部署、设备连接等基础设施见 `ohos-dev-distributed-mmi-device-test-harness`。 ## When to Use - 提交 PR 前需要量化代码变更对二进制体积的影响 - 需要证明重构/新特性不引入内存膨胀 - 评审要求提供 RAM/ROM 数据 ## Safety and Comparability Gates Replacing system `.so` files, remounting `/` read-write, and rebooting a device are destructive test operations. Do them only after explicit user approval, keep `.bak` copies of every replaced library, and restore the device to the requested final state before ending the workflow. A RAM/ROM conclusion is only comparable when these conditions are recorded: - baseline and current image/build or `.so` provenance - exact libraries replaced - whether the same functional path was executed before both captures - whether process-level numbers are idle-vs-idle, exercised-vs-exercised, or mixed If baseline is idle but current is post-exercise, do not present process-level PSS delta as feature RAM cost. Use it only as context and rely on library PSS plus code-level theoretical analysis. ## 度量三支柱 本 skill 要求从三个互相佐证的维度度量 RAM 影响: | 维度 | 方法 | 反映什么 | 局限 | |------|------|---------|------| | **ROM 段级** | `readelf -S` | 静态映射内存(.text/.rodata/.bss) | 不反映堆分配 | | **RAM 实测** | smaps + hidumper 真机采集 | 进程实际物理内存 | 受采集条件/编译差异影响 | | **RAM 理论** | git diff 分析新增容器 + 结构体估算 | 堆分配和运行时数据结构 | 人工估算,依赖正确的结构体大小分析 | 三个维度**必须同时完成**,互相交叉验证。仅做段级估算会遗漏堆分配;仅做实测会受噪声影响;仅做理论分析无法确认实际表现。 ## 度量目标库和进程范围 先根据代码变更确定影响面,不要默认只看服务端进程。至少检查改动是否触达以下库: | 库 | 角色 | RAM 分析范围 | |----|------|-------------| | `libmmi-server.z.so` | 服务端主逻辑 | `multimodalinput` 进程 | | `libmmi-server-common.z.so` | 服务端公共 | `multimodalinput` 进程 | | `libmmi-util.z.so` | 工具库 | 所有加载该库的目标进程 | | `libmmi-client.z.so` | 客户端 API/代理 | 触发该 API 的客户端进程,不能用服务端进程 PSS 代表 | 规则: - ROM 分析应覆盖所有受影响的 libmmi `.so`,包括 `libmmi-client.z.so`。 - RAM 分析必须按实际加载进程归属。`libmmi-client.z.so` 通常不在 `multimodalinput` 服务端进程中加载;如果客户端 API、proxy、NAPI 或测试二进制路径受影响,需要选择一个会加载 `libmmi-client.z.so` 的客户端进程执行功能路径并采集该进程的 smaps/hidumper 数据。 - 如果改动只影响服务端内部路径,可以说明 client so 未加载到服务端进程,但仍要用代码 diff、符号 或段级数据确认 `libmmi-client.z.so` 是否真的无变化或不参与本次 RAM 结论。 - 最终报告要列出“库 → 进程 → 是否执行功能路径 → 是否纳入 RAM 结论”的映射,避免把服务端 PSS 误当成全量 MMI RAM 成本。 ## ROM 度量方法 ### 1. 文件级对比(快速) ```bash BUILD_OUT="code/out/rk3568/multimodalinput/input" ls -la $BUILD_OUT/libmmi-*.z.so ``` ### 2. 段级对比(精确,推荐) 使用 `readelf -S` 分析关键段: ```bash readelf -S libmmi-server.z.so | grep -E '\.text|\.rodata|\.data|\.bss' ``` | 段 | 含义 | 影响 | |----|------|------| | `.text` | 可执行代码 | 直接影响 ROM;映射为 shared clean 影响 RAM PSS | | `.rodata` | 只读数据(字符串常量等) | 影响 ROM 和 shared clean PSS | | `.data` | 已初始化全局变量 | 影响 ROM 和 private dirty | | `.bss` | 零初始化全局变量 | 不影响 ROM;影响 anonymous RAM | | `.data.rel.ro` | 重定位后只读 | 影响 ROM | ### 3. 基线获取策略 **方案 A:设备 .bak 文件**(推荐) 部署修改版 .so 前,先备份原始 .so: ```bash $HDC shell "cp /system/lib/libmmi-server.z.so /data/local/tmp/libmmi-server.z.so.bak" # 部署新 .so... # 之后拉取基线 $HDC file recv /data/local/tmp/libmmi-server.z.so.bak ./libmmi-server.z.so.bak ``` **方案 B:CI 基线构建** 从 CI 每日构建镜像中提取同版本 .so 作为基线。 ## RAM 度量方法 ### 1. 找到进程 PID ```bash $HDC shell "pidof multimodalinput" ``` **注意 PID 稳定性**:multimodalinput 是系统服务,可能被 watchdog 重启导致 PID 变化。在多条 hdc 命令之间 PID 可能不同。**解决方案**:使用命令替换在单次 hdc shell 调用中完成 PID 查找和数据采集: ```bash $HDC shell "cat /proc/\$(pidof multimodalinput)/smaps_rollup" ``` ### 2. smaps_rollup(进程级汇总) ```bash $HDC shell "cat /proc/\$(pidof multimodalinput)/smaps_rollup" ``` 关键字段: - **Pss**: 按共享比例分摊后的实际物理内存(最能反映真实占用) - **Rss**: 驻留物理内存(包含共享页全量) - **Size**: 虚拟地址空间大小 ### 3. smaps per-library PSS(重要) ```bash $HDC shell "cat /proc/\$(pidof multimodalinput)/smaps" > smaps.txt ``` 解析脚本和注意事项见 `references/smaps-pss-attribution.md`。关键要求是每个 mapping header 都要重置当前库名,避免把 anonymous PSS 错归到上一个 `.so`。 ### 4. hidumper --mem(系统级) ```bash $HDC shell "hidumper --mem \$(pidof multimodalinput)" ``` 输出包含:native heap、.so mmap PSS、total PSS 等分类。 **注意**:hidumper 输出可能很长,通过 hdc shell 可能被截断。可重定向到文件后拉取: ```bash $HDC shell "hidumper --mem \$(pidof multimodalinput) > /data/local/tmp/hidumper_mem.txt" $HDC file recv /data/local/tmp/hidumper_mem.txt ./hidumper_mem.txt ``` ### 5. RAM 增量归因(必须) 每一个 RAM 增长结论都必须回答“增长来自哪里”。不能只报告 total PSS 或 `multimodalinput` 进程 PSS 差值。至少把增长拆成以下来源并给出证据: | 来源 | 证据 | 处理要求 | |------|------|----------| | 新增/变化的 `.so` 映射 | baseline/current smaps 中的 mapped `.so` 列表和 PSS | 列出每个 `.so` 的基线 PSS、当前 PSS、差值、是否新增加载 | | libmmi 代码段变化 | `readelf -S` + smaps per-library PSS | 单独列出 libmmi 各库 PSS 增量和对应 section 差异 | | native heap 增长 | `hidumper --mem` native heap + 代码 diff | 对应到新增容器、对象、缓存、RS 资源或生命周期状态 | | anonymous/file PSS 增长 | smaps_rollup `Pss_Anon`/`Pss_File` 或 smaps 分类 | 说明是否来自堆、匿名映射、文件映射、测试框架或系统状态 | | 测试环境/框架噪声 | 新增加载的测试二进制依赖、input-test 框架等 `.so` | 与目标特性分开,不得直接归因给代码变更 | | 未归因残差 | total delta - 已解释 delta | 单独列出;残差过大时结论只能标记为“不完整归因” | 推荐从 smaps 中按完整路径聚合所有 `.so` PSS,而不是只匹配 `libmmi`;参考脚本见 `references/smaps-pss-attribution.md`。 对 baseline/current 两份结果做 outer join,生成“新增/变化的已加载 `.so`”表: | 进程 | `.so` 路径 | 基线 PSS(kB) | 当前 PSS(kB) | 差值(kB) | 是否新增加载 | 归因 | |------|-----------|--------------|--------------|----------|--------------|------| | multimodalinput | /system/lib/libmmi-server.z.so | X | Y | +/-Z | no | libmmi server 代码段变化 | | multimodalinput | /system/lib/libxxx.z.so | 0 | Y | +Y | yes | 功能路径触发 / 测试框架 / 环境噪声 | 如果内存增长主要来自加载了新的 `.so`,报告必须列出这些 `.so` 的名称、路径、 PSS 增量和触发原因;不能只写“.so mmap PSS 增长”。如果无法证明某个新加载库由目标 特性触发,应归入“环境/测试框架差异”或“未归因”,不要归入目标特性成本。 ### 6. 基线 RAM 获取 **精确方法**:临时恢复 .bak .so → 重启 → 采集 → 恢复修改版 .so ```bash # 1. 备份当前修改版 $HDC shell "mount -o rw,remount /" # RK3568 根文件系统在 /,不是 /system $HDC shell "cp /system/lib/libmmi-server.z.so /data/local/tmp/libmmi-server.z.so.new" # 对 libmmi-server-common.z.so, libmmi-util.z.so 同样操作 # 2. 恢复基线 $HDC shell "cp /data/local/tmp/libmmi-server.z.so.bak /system/lib/libmmi-server.z.so" # 对每个库同样恢复 .bak $HDC shell "reboot" # 等待重启 (~60s)... # 3. 采集基线 RAM $HDC shell "cat /proc/\$(pidof multimodalinput)/smaps_rollup" $HDC shell "cat /proc/\$(pidof multimodalinput)/smaps" > smaps_baseline.txt $HDC shell "hidumper --mem \$(pidof multimodalinput) > /data/local/tmp/hidumper_baseline.txt" # 4. 恢复修改版 $HDC shell "mount -o rw,remount /" $HDC shell "cp /data/local/tmp/libmmi-server.z.so.new /system/lib/libmmi-server.z.so" # 对每个库同样恢复 .new $HDC shell "reboot" ``` > **RK3568 mount 注意**:根文件系统挂载在 `/`,不是 `/system`。`mount -o rw,remount /system` 会报 "not in /proc/mounts" 错误。正确命令是 `mount -o rw,remount /`。 **估算方法**(不需要重启): 基于段级分析推算 RAM 变化: - `.text` + `.rodata` 差值 → 影响 shared clean PSS - `.bss` 差值 → 影响 anonymous 内存 - `.data` 差值 → 影响 private dirty 当段差值很小(< 1%)且 `.bss` 无变化时,可以直接用估算方法而无需重启。 ### 7. 采集前必须执行功能路径 **关键约束**:仅部署 .so 并重启是不够的。如果变更引入了懒分配(lazy allocation)的数据结构,必须在采集前执行完整的功能路径,确保所有运行时状态被实际分配: ``` 部署 .so → 重启 → 等待系统稳定 (30s) → 执行功能路径 → 等待稳定 (5s) → 采集 ``` 功能路径按变更内容定义,不要固定成某一个特性用例。通用模板: 1. 初始化变更依赖的系统状态(如 display、window、device、session、permission)。 2. 调用新增或修改的 public API、IPC、server handler、callback 或事件路径。 3. 触发懒分配和缓存路径(如首次事件、重复事件、边界设备、窗口、显示组)。 4. 覆盖清理路径(解绑、销毁、断连、窗口删除、服务重启前后状态)。 5. 记录实际执行的步骤,并说明哪些受影响库和进程被该路径覆盖。 例如 display group 绑定可以用 `UpdateDisplayInfo`、`UpdateWindowInfo`、 `BindDeviceToDisplayGroupByDisplay` 和事件注入触发;其他特性必须替换成自己的最小完备功能路径。 不执行功能路径的 RAM 采集会**低估**实际内存占用,因为懒分配的容器仍为空。 ## 代码理论分析方法(第三支柱) 段级估算只能反映静态映射内存,无法反映堆分配(new/malloc)。对于引入新数据结构的特性变更,**必须**分析代码 diff 中的新增容器和对象。 详细估算规则见 `references/theoretical-ram-estimation.md`。主流程只要求输出: - 新增容器、对象、缓存和 RS 资源清单。 - 每类对象的典型场景和上界场景估算。 - 分配时机、清理路径和泄漏风险。 - 理论估算与实测 libmmi PSS/native heap/Pss_Anon 的交叉验证结论。 ## 输出报告模板 ```markdown ## ROM 影响 ### 文件级对比 | 库 | 基线(bytes) | 当前(bytes) | 差值 | 比例 | |----|------------|------------|------|------| | libmmi-server.z.so | X | Y | +/-Z | +/-N% | | ... | | | | | | **合计** | | | | | ### libmmi-server.z.so 段级分析 | 段 | 基线 | 当前 | 差值 | |----|------|------|------| | .text | X | Y | +/-Z | | .rodata | | | | | .data | | | | | .bss | | | | ### 影响范围映射 | 库 | 受影响代码路径 | 目标进程 | 是否采集 RAM | 说明 | |----|--------------|----------|--------------|------| | libmmi-server.z.so | server handler / event path | multimodalinput | yes/no | | | libmmi-client.z.so | client API / proxy / NAPI | <client-process-or-test-binary> | yes/no | | ## RAM 影响 ### RAM 增长原因归因 #### 进程级增量拆解 | 指标/类别 | 基线(kB) | 当前(kB) | 差值(kB) | 证据来源 | 归因 | |-----------|----------|----------|----------|----------|------| | total PSS | X | Y | +/-Z | smaps_rollup / hidumper | 汇总,仅作入口 | | .so mmap PSS | X | Y | +/-Z | hidumper + smaps `.so` 聚合 | 见“已加载 .so 增量”表 | | native heap | X | Y | +/-Z | hidumper | 见“heap/anonymous 增量”表 | | Pss_Anon | X | Y | +/-Z | smaps_rollup | heap/anonymous/运行时状态 | | Pss_File | X | Y | +/-Z | smaps_rollup | 文件映射或加载库变化 | #### 已加载 .so 增量 | 进程 | `.so` 路径 | 基线 PSS(kB) | 当前 PSS(kB) | 差值(kB) | 是否新增加载 | 触发路径/归因 | |------|-----------|--------------|--------------|----------|--------------|---------------| | multimodalinput | /system/lib/libmmi-server.z.so | X | Y | +/-Z | no | 目标 libmmi 代码变化 | | <process> | /system/lib/libxxx.z.so | 0 | Y | +Y | yes | 功能路径触发 / 测试框架 / 环境噪声 | #### libmmi PSS 增量 | 库 | 基线 PSS (kB) | 当前 PSS (kB) | 差值 | section 证据 | 归因 |
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る