js常见的内存泄漏

164 阅读2分钟

内存泄漏是我们日常开发中因为代码的不规范制造出的无法被浏览器垃圾回收器回收的变量,所以了解内存泄漏产生的原因就很重要了

什么样的变量的变量不会被垃圾回收器回收呢,一般来说就是一个变量被另一个变量引用,迫使它一直保持引用状态,由于这个引用关系,导致浏览器认为它还是从前那个变量没有一丝丝改变,只是不再会被使用,但当初的内存丝毫未减,就像下面这样:

const test = (function () {
  const 变量 = 5;
  return function () {
    console.log(变量, '我还是那个变量,没有一丝丝改变')
  }
})()

只要test没有被回收,那么这个变量就会一直在内存中呆着,一个也就罢了,一堆该怎么办,浏览器不得炸给你看呀,内存不足会造成不断 GC,而 GC 时是会阻塞主线程的,所以会影响到页面性能,造成卡顿,所以内存泄漏问题还是需要关注的

那么怎么样才能让垃圾回收器将变量回收呢,很简单,你只要在不使用这个变量的时候将它赋值为null就可以了,当null是会脱离执行环境,这样下次垃圾回收器就能逮到它了

除了上面的例子之外,日常开发中可能还会有js引用dom元素,注册定时器没有消除,注册事件没有消除等一系列的因素导致内存泄漏,下面举几个栗子:

dom内存泄漏:

<!DOCTYPE html>
<html lang="en">
  <body>
    <div id="app"></div>
  </body>
</html>
<script>
let app = app;
document.body.removeChild(app); // 你以为删除了,其实它还在,因为js引用了它
// app = null; 这样才可以删除呦
</script>

定时器引起的内存泄漏:

const timeId = setInterval(() => {console.log('爱像一道光,绿到你发慌')})
// clearInterval(timeId); 这样才可以删除呦

事件监听造成内存泄漏:

<div id="app">点我</div>
app.addEventListener('click', () => {console.log('再点我,我就炸给你看');})
// document.body.removeEventListener('click'); 这样才可以删除呦