3.3 KiB
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 生命周期错配。
优化方案
- manager 明确持有当前完整图和半图 PixelMap,并在 dialog dismiss 后延迟 300 ms 释放,避免关闭动画仍使用图片。
- 单图失败、弹窗 show 失败和异步任务过期时立即释放已创建但未展示的 PixelMap。
- 使用 generation 标记使旧异步创建失效,避免旧结果覆盖新弹窗。
floatBallIds改为Set<string>,销毁后清空;兜底 dismiss 仍按历史登记 ID 匹配当前页面 dialog。- 对同一 PixelMap 被同时作为完整图和半图的异常情况只调用一次
release()。
影响范围
- 仅修改首页广告悬浮球的图片与 dialog 生命周期管理。
- 不修改广告数据、图片地址、展示样式、点击行为或 300 ms 创建防抖。
- 延迟释放只持有已 dismiss 的当前两张图片 300 ms,避免立即释放与弹窗关闭动画竞争。
预期收益与边界
成功展示的每个悬浮球最多持有当前 2 张 PixelMap,销毁后释放;单图失败不再残留另一张;ID 集合在销毁后归零。Native 图片内存收益取决于图片尺寸、像素格式和系统解码缓存,本次未取得真实图片尺寸与设备 PSS,因此不估算具体 MB。
该修复不治理其他广告弹窗、网络图片缓存、系统图形缓存或 GPU/DMA 内存,也不代表 Native PSS 会在 release 后立即同步下降。
验证结果
- 对实际
AdsBallManager.ets转译后执行 5,000 轮成功创建/销毁、5,000 轮半图失败和 1 轮异步过期压力测试。 - 共创建 15,001 个模拟 PixelMap,全部恰好释放一次;最终 retained dialog ID 为 0、retained dialog 为 0。
- 新实现随主工程通过直接 Hvigor
entry@defaultDebug HAP 构建,完整 ArkTS 编译、打包和签名成功;未执行安装。 - 压力测试中将 300 ms 延迟计时器同步触发以校验所有权计数;真实设备关闭动画时序、Native PSS 回落和 OOM 日志未验证。
- 临时压力测试代码与日志已删除,未在生产代码中保留调试计数。
- 2026-08-21 在 Pura 90 API 24 模拟器确认首页 VIP 广告真实展示并成功关闭,关闭后底部 Tab 恢复可操作;同次测试未发现 OOM、JS Crash、CppCrash、SIGSEGV 或 SIGABRT。
- 本次设备操作只完成 1 次真实广告展示/关闭,未取得 PixelMap Native 归属计数,也未完成 50~100 轮重复广告创建,因此不宣称真实设备 Native PSS 稳态已经验证;重复释放正确性仍以 15,001 个模拟 PixelMap 的白盒压力测试为依据。