2021-11-14 04:20:38
JavaScript中的WeakRef和FinalizationRegistry通过弱引用和对象回收后回调机制辅助内存管理,主要用于避免内存泄漏,但需谨慎使用。
一、WeakRef的内存管理机制通过new WeakRef(obj)创建弱引用。
调用deref()方法获取对象:若对象未被回收,返回对象本身;若已被回收,返回undefined。
const obj = { data: 'example' };const weakRef = new WeakRef(obj);const value = weakRef.deref();if (value) { console.log(value.data); // 对象存在时输出}仅适用于对象,不能用于原始值(如字符串、数字)。
不保证对象存活,频繁调用deref()可能导致性能下降。
通过new FinalizationRegistry(callback)创建注册表,回调函数接收注册时的附加数据。
调用register(obj, heldValue)注册对象,传入对象和附加数据。
const registry = new FinalizationRegistry((heldValue) => { console.log('对象被回收,附加数据:', heldValue);});const obj = { name: 'test' };registry.register(obj, 'metadata-about-obj');不保证执行时机:回调可能在对象回收后立即执行,也可能延迟执行。
不保证执行顺序:多个对象的回调执行顺序不确定。
仅作为提示:不可依赖其进行关键资源清理(如关闭文件句柄)。
缓存:WeakRef可用于缓存对象,避免强引用导致内存无法释放。
观察器模式:监控对象生命周期,在对象回收时执行非关键操作。
绑定原生资源:如DOM元素或文件句柄,但需结合其他机制确保资源释放。
不可依赖关键清理:FinalizationRegistry的回调不保证执行,关键资源(如数据库连接)需手动管理。
无法解决循环引用:WeakRef和FinalizationRegistry不能处理对象间的循环引用,仍需合理设计对象结构。
性能影响:频繁使用WeakRef可能导致GC压力增加,影响性能。
替代方案优先:优先使用强引用管理资源,仅在必要时使用弱引用和终结回调。
WeakRef和FinalizationRegistry为JavaScript提供了更灵活的内存管理工具,但需明确其局限性: