一 JS那些操作会引起内存泄露,如何避免?

JavaScript中引起内存泄露的操作主要与不恰当的引用管理和资源分配有关。

1.1 循环引用

当两个或多个对象相互引用,形成一个闭环,而这些对象又不再被外部所引用时,垃圾回收器无法回收它们,导致内存泄露。

避免方法:

  • 使用WeakMapWeakSet来存储对象引用,这样当对象没有其他强引用时,垃圾回收器仍然可以回收它们
  • 定期断开不再需要的引用,尤其是在离开作用域前

1.2 未清理的定时器和事件监听器

设置的 setTimeoutsetInterval 或事件监听器(如 click 事件)如果未被正确清除,会一直持有对回调函数及其上下文的引用,阻止它们被回收

避免方法:

  • 使用clearTimeoutclearInterval来取消不再需要的定时器
  • 在组件卸载或不再需要事件时,使用removeEventListener移除事件监听器

1.3 未释放的 DOM 元素引用

在操作DOM时,如果闭包或者其他方式意外持有了对DOM元素的引用,即使DOM元素已从页面中移除,这些引用也可能阻止DOM节点及其相关子树被回收

避免方法:

  • 确保在操作DOM后,解除不再需要的引用,特别是当与事件处理器一起使用闭包时
  • 使用null赋值给不再使用的DOM引用,明确断开引用关系

1.4 全局变量

全局变量在整个应用程序生命周期内都可访问,如果不当使用,容易导致不必要的内存占用

避免方法:

  • 尽量使用局部变量
  • 对于需要跨作用域共享的数据,考虑使用模块模式或封装在对象内部

1.5 没有清理的缓存和数据结构

应用程序内部创建的缓存、对象池等,如果没有有效的清理机制,随着时间积累,可能会占用大量内存

避免方法:

  • 实现缓存淘汰策略,如LRU(Least Recently Used)算法,定期清理不再活跃的缓存项
  • 监控和限制数据结构的大小,适时清除不再需要的数据