用 weakref 构建异步地图瓦片数据池,核心是按需保留活跃瓦片:map 仅存弱引用元信息,配合 finalizationregistry 自动清理幽灵键,并通过 timestamp/priority 实现惰性加载与智能淘汰。

用 WeakRef 构建异步地图瓦片原始数据池,核心不是“存住所有瓦片”,而是让内存只保留当前活跃、正在被渲染或即将被使用的瓦片数据,其余自动释放。关键在于把 WeakRef 当作“观察哨”,配合异步加载逻辑和生命周期感知,实现真正按需——不预占、不滞留、不泄漏。
瓦片数据池的基础结构设计
池子本身不用强引用持有瓦片数据(如 ArrayBuffer、ImageBitmap 或 GeoJSON 片段),而是用 Map
-
tileKey 通常由
z/x/y+ 投影类型(如webmercator)构成,确保唯一可索引 - ref 持有弱引用,允许 GC 在无其他引用时回收原始数据
- timestamp 和 priority 用于后续淘汰或重载决策,比如视口内瓦片优先级更高
加载与获取的异步流程
调用 getTileData(key) 时,并非直接返回数据,而是走判断+加载双路径:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 先查 Map 中是否存在该 key;若存在,调用
ref.deref() - 若
deref()返回undefined,说明数据已被回收 → 触发异步加载(例如 fetch 对应瓦片 URL,或解码本地缓存 blob) - 加载成功后,新建 WeakRef 包裹结果,更新 Map 条目,并附上当前时间戳
- 整个过程对上层渲染逻辑透明,渲染层仍可 await 获取数据,但底层不阻塞也不强持
配合 FinalizationRegistry 实现自动清理
仅靠 WeakRef 不知道“什么时候没了”,必须注册 FinalizationRegistry 主动响应销毁:
- 注册时传入一个 cleanup callback,参数为 tileKey(需在注册时作为 held value 传入)
- 每次 new WeakRef(data) 后,立即调用
registry.register(data, tileKey) - 当 data 被 GC 回收,callback 触发,从 Map 中删除对应条目,避免“幽灵键”堆积
- 这一步让池子具备自愈能力:即使开发者忘记手动清理,也不会内存泄漏
与地图渲染行为联动的惰性策略
“按需”不止是首次请求,更体现在使用节奏上:
- 瓦片数据只在 首次绑定到 WebGL 纹理 或 准备转为 ImageBitmap 供 canvas 使用前一刻 才加载
- 平移/缩放过程中,对即将进入视口的瓦片(比如 buffer 区域)可提前触发
prefetch(key),但它仍走同一套 WeakRef 流程,不强制驻留 - 不维护固定容量上限,而是通过定期扫描 Map,按
timestamp清理长时间未访问(如 >30s)且优先级低的条目(仅删 Map 记录,WeakRef 自动失效)










