3.4 KiB
3.4 KiB
行情表格请求切换的订阅与缓冲清理
修复提交
| 仓库 | 分支 | Commit ID | 说明 |
|---|---|---|---|
harmony-ths-futures-apm-oom |
work-20260820-clz-FUHM-1979-apm-oom |
5f6e007c7f431521350a68543c4db5314a8c644f |
修复 TableRequestClient 订阅泄漏 |
harmony-ths-futures-apm-oom |
work-20260820-clz-FUHM-1979-apm-oom |
2ca4759c4e0212b4c80c41b94a0ae1339569e89c |
完善请求切换时的统一清理逻辑 |
问题
行情列表通过 TableRequestClient 发起请求,并在带 newrealtime=1 的请求中向 RealDataManager 注册实时订阅。请求队列映射、实时订阅和请求缓冲分别以 instanceId、instanceId、frameId + pageId + instanceId 关联。
原有 setPageId() 先覆盖成员 pageId,再移除请求队列映射;随后无法获得旧 instanceId,也没有同步清理旧实时订阅与旧请求缓冲。切换行情分组时,RealDataManager 可能持续持有旧表格订阅并合并推送数据,造成 Local Heap 持续增长,最终有 OOM 风险。
优化方案
setPageId()在覆盖成员前保存旧pageId,递增请求生命周期版本并取消待执行通知,再统一解绑旧请求。- 新增私有
detachCurrentRequest(oldPageId):调用RequestQueueManagement.removeByClient(this)原子取得并移除旧 instanceId 映射;当旧 ID 有效时,用该 ID 移除RealDataManager订阅,并以旧pageId删除对应请求缓冲。 removeSubscriber()与release()复用同一解绑逻辑,避免多个生命周期出口清理策略不一致。- 保留既有异步版本校验和
setTimeout取消逻辑,防止过期解析结果或通知闭包继续持有表格数据。
影响范围
- 仅修改
lib_baseUI的TableRequestClient请求切换和释放生命周期。 - 不修改协议报文、请求参数、表格解析、实时数据合并或 UI 展示逻辑。
- 请求未建立队列映射时,清理操作保持幂等并直接返回。
预期收益与边界
每次行情分组切换和页面销毁都会同时释放旧请求的队列映射、实时订阅及请求缓冲,避免孤儿订阅继续持有全量表格并接收实时推送,从而抑制 Local Heap 随切页线性增长。
该修改只治理 TableRequestClient 链路的引用滞留;图形内存、Web、Native/CPP 堆及其他业务模块的内存增长仍需按各自链路继续分析。removeSubscriber 与缓冲删除均按旧 instanceId 执行,因此不会误删新请求。
验证建议
- 执行
devecocli build --modules entry@default,确认 ArkTS 编译和打包通过。 - 安装新 HAP 后,在“行情 → 国内”页的“全部主力 / 能源”等分组间连续切换 20~50 次,再离开列表页。
- 使用临时调试计数验证每次切换后旧订阅和旧请求缓冲各减少一项,待执行通知数归零;验证完成后不保留计数日志或缓冲快照统计代码。
- 检查应用崩溃日志,并结合 APM/HiLog 观察 Local Heap 在循环切换期间不再线性增长。
本次验证结果
在模拟器上完成 20 次同一活跃 TableRequestClient 的分组切换:每轮旧订阅数由 2 降至 1、请求缓冲数由 4 降至 3,待执行通知数始终为 0;离开行情列表后订阅数由 1 降至 0。未发现该应用的崩溃日志。上述计数日志仅用于本次验收,已从正式代码移除。