无需登录 数据私有 本地保存

WeakMap/WeakSet 内存回收演示 - 弱引用可视化

15
0
0
0
快速开始

打开工具页面后,您将看到四个数据结构面板(Map、WeakMap、Set、WeakSet)和一个操作日志面板。顶部工具栏提供了创建对象、执行操作和触发 GC 模拟的核心按钮。左侧的对象池区域显示所有已创建但尚未分配的对象,右侧的状态面板实时展示 FinalizationRegistry 的回调信息。建议从第一个示例开始,逐步熟悉每个操作的效果,整个学习过程大约需要10-15分钟。

步骤 1
创建测试对象

点击"创建对象"按钮,工具会自动生成一个新的 JavaScript 对象实例(包含唯一 ID 和随机属性值)。新对象会显示在"待分配对象池"中,状态标记为"已创建-未分配"。建议创建 2-3 个对象,以便后续进行对比实验。每个对象都会附带一个简要的属性摘要,方便在后续操作中快速识别和追踪。

步骤 2
分配到数据结构

在对象池中选择目标对象,然后点击目标数据结构(Map/WeakMap/Set/WeakSet)的"添加"按钮。添加时需要指定键名(Map/WeakMap)或确认为集合元素(Set/WeakSet)。添加成功后,对象会从对象池移至对应的结构面板中,引用状态显示为"强引用"或"弱引用"。建议同时将同一个对象分别添加到 Map 和 WeakMap 中,以便后续对比两种结构在引用管理上的差异。

步骤 3
释放强引用

选择一个已分配的对象,点击"释放强引用"按钮。此操作模拟将外部变量设为 null 的行为。对于 Map/Set 中的对象,即使外部引用释放,集合内仍持有强引用,对象状态保持"存活";对于 WeakMap/WeakSet 中的对象,外部引用释放后,对象仅存弱引用,状态变为"待回收"。观察此时各面板中的状态差异,这是理解弱引用核心特性的关键步骤。注意观察状态标签从"强引用"变为"弱引用"的过程。

步骤 4
从集合中移除

选择一个已分配的对象,点击目标集合的"移除"按钮。此操作模拟从 Map/Set 中 delete 或从 WeakMap/WeakSet 中移除弱引用键。移除后,对象的引用状态会更新:若无任何引用持有,则标记为"已释放"。注意观察移除操作对不同数据结构的影响差异。这一步可以帮助您理解手动清理与自动回收之间的区别,以及在什么场景下需要主动移除集合元素。

步骤 5
触发 GC 模拟

点击"触发 GC 模拟"按钮,工具会模拟垃圾回收器的行为。GC 会检查所有弱引用对象:若对象仅存弱引用(外部已释放且未在强引用集合中),则标记为"已回收"并触发 FinalizationRegistry 回调。观察 FinalizationRegistry 监听面板中回调的执行记录,以及各面板中对象状态的变化。建议多次触发 GC 模拟,观察不同操作顺序对回收结果的影响。每次 GC 模拟后,工具会在日志中生成一份回收摘要,列出本次被回收的对象数量和释放的内存估算值,帮助您量化理解弱引用对内存管理的实际贡献。

步骤 6
查看操作日志

在底部操作日志面板中,您可以回溯完整的操作序列。每条日志包含时间戳、操作类型、对象 ID 和状态变化信息。使用日志筛选功能可以按操作类型或对象 ID 过滤,便于分析特定对象的完整生命周期。建议在每次 GC 模拟后查看日志,确认回收事件的记录,并将日志中的时间戳与 FinalizationRegistry 回调的触发时间进行对比分析。

步骤 7
进阶实验:缓存场景模拟

尝试模拟一个典型的缓存场景:创建多个对象加入 WeakMap(模拟缓存键值对),然后逐一释放外部强引用。触发 GC 后,观察哪些对象被回收、哪些被保留。再用 Map 重复相同操作,对比两种数据结构在缓存淘汰策略上的差异。这个实验能帮助您深刻理解 WeakMap 在缓存管理中的实际优势。您还可以尝试模拟 DOM 节点元数据管理的场景,进一步扩展对弱引用应用场景的理解。