什么是?哪些情况会导致内存泄漏?
题干
- 内存泄漏(Memory leak)
题解
内存泄漏是指程序在申请内存后,无法释放已申请的内存空间,导致这些内存空间无法被再次使用,从而造成内存资源的浪费和紧张。内存泄漏可能会导致程序性能下降,甚至崩溃或者出现异常错误。
简单点来说,针对 JS ,虽然引擎针对垃圾回收做了各种优化从而尽可能的确保垃圾得以回收,但并不是所有无用对象内存都可以被回收的,那当不再用到的对象内存,没有及时被回收时,我们叫它 内存泄漏。
常见的会引起内存泄漏的点:
不正当的闭包:闭包的特性就是为了缓存引用关系,所以也会产生内存泄漏,我们可以在函数调用后,把外部的引用关系置空。
隐式全局变量:对于全局变量,垃圾回收器很难判断这些变量什么时候才不被需要,所以全局变量通常不会被回收,我们使用全局变量是 OK 的,但同时我们要避免一些额外的全局变量产生。
游离的 DOM 引用:我们代码中进行
DOM
时会使用变量缓存DOM
节点的引用,但移除节点的时候,我们应该同步释放缓存的引用,否则游离的子树无法释放。遗忘的定时器:当不需要
interval
或者timeout
时,最好调用clearInterval
或者clearTimeout
来清除,另外,浏览器中的requestAnimationFrame
也存在这个问题,我们需要在不需要的时候用cancelAnimationFrame API
来取消使用,不然也会引起内存泄漏。遗忘的事件监听器:当事件监听器在组件内挂载相关的事件处理函数,而在组件销毁时不主动将其清除时,其中引用的变量或者函数都被认为是需要的而不会进行回收,如果内部引用的变量存储了大量数据,可能会引起页面占用内存过高,这样就造成意外的内存泄漏。
遗忘的监听者模式:当我们实现了监听者模式并在组件内挂载相关的事件处理函数,而在组件销毁时不主动将其清除时,其中引用的变量或者函数都被认为是需要的而不会进行回收,如果内部引用的变量存储了大量数据,可能会引起页面占用内存过高,这样也会造成意外的内存泄漏。
遗忘的 Map、Set 对象:当使用
Map
或Set
存储对象时,同Object
一致都是强引用,如果不将其主动清除引用,其同样会造成内存不自动进行回收。可以采用WeakMap
,WeakMap
!未及时清理的 Console 输出:之所以在控制台能看到数据输出,是因为浏览器保存了我们输出对象的信息数据引用,也正是因此未清理的
console
如果输出了对象也会造成内存泄漏。