Files
future-harmony-freeze-oom-fix/harmony-ths-futures-apm-oom/doc/change-notes/15-ads-ball-pixelmap-id-cleanup.md
T

3.3 KiB

广告悬浮球 PixelMap 与 Dialog ID 生命周期清理

修复提交

仓库 分支 Commit ID 说明
harmony-ths-futures-apm-oom work-20260820-clz-FUHM-1979-apm-oom da5599387d82f06256e9224eb8c8001410de1a6b 释放广告 PixelMap、失效异步创建并清空 ID

问题

AdsBallManager 创建完整图和半图 PixelMap 后未保存并显式释放所有权。任一图片加载失败时,另一张已成功创建的 PixelMap 会直接遗漏;弹窗销毁也只 dismiss dialog,不释放 Native 图片资源。floatBallIds 使用只增不删的数组,主题切换和广告刷新会长期保留历史 ID。

异步图片加载期间如果发生新的创建或销毁,旧任务还可能在完成后覆盖新弹窗,使旧图片和 dialog 生命周期错配。

优化方案

  1. manager 明确持有当前完整图和半图 PixelMap,并在 dialog dismiss 后延迟 300 ms 释放,避免关闭动画仍使用图片。
  2. 单图失败、弹窗 show 失败和异步任务过期时立即释放已创建但未展示的 PixelMap。
  3. 使用 generation 标记使旧异步创建失效,避免旧结果覆盖新弹窗。
  4. floatBallIds 改为 Set<string>,销毁后清空;兜底 dismiss 仍按历史登记 ID 匹配当前页面 dialog。
  5. 对同一 PixelMap 被同时作为完整图和半图的异常情况只调用一次 release()

影响范围

  • 仅修改首页广告悬浮球的图片与 dialog 生命周期管理。
  • 不修改广告数据、图片地址、展示样式、点击行为或 300 ms 创建防抖。
  • 延迟释放只持有已 dismiss 的当前两张图片 300 ms,避免立即释放与弹窗关闭动画竞争。

预期收益与边界

成功展示的每个悬浮球最多持有当前 2 张 PixelMap,销毁后释放;单图失败不再残留另一张;ID 集合在销毁后归零。Native 图片内存收益取决于图片尺寸、像素格式和系统解码缓存,本次未取得真实图片尺寸与设备 PSS,因此不估算具体 MB。

该修复不治理其他广告弹窗、网络图片缓存、系统图形缓存或 GPU/DMA 内存,也不代表 Native PSS 会在 release 后立即同步下降。

验证结果

  1. 对实际 AdsBallManager.ets 转译后执行 5,000 轮成功创建/销毁、5,000 轮半图失败和 1 轮异步过期压力测试。
  2. 共创建 15,001 个模拟 PixelMap,全部恰好释放一次;最终 retained dialog ID 为 0、retained dialog 为 0。
  3. 新实现随主工程通过直接 Hvigor entry@default Debug HAP 构建,完整 ArkTS 编译、打包和签名成功;未执行安装。
  4. 压力测试中将 300 ms 延迟计时器同步触发以校验所有权计数;真实设备关闭动画时序、Native PSS 回落和 OOM 日志未验证。
  5. 临时压力测试代码与日志已删除,未在生产代码中保留调试计数。
  6. 2026-08-21 在 Pura 90 API 24 模拟器确认首页 VIP 广告真实展示并成功关闭,关闭后底部 Tab 恢复可操作;同次测试未发现 OOM、JS Crash、CppCrash、SIGSEGV 或 SIGABRT。
  7. 本次设备操作只完成 1 次真实广告展示/关闭,未取得 PixelMap Native 归属计数,也未完成 50~100 轮重复广告创建,因此不宣称真实设备 Native PSS 稳态已经验证;重复释放正确性仍以 15,001 个模拟 PixelMap 的白盒压力测试为依据。