【前端--JavaScript】知识点(五)—— 项目中的内存泄漏(一)

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战**node

最近在写小程序的过程当中,用到了不少的console.log,开始是为了联调方便,一直没有删除,致使页面时不时有卡顿现象出现,开始以为页面从新刷新就行了,可是产品和测试不会答应的呀,后来排查了一下问题,才发现页面中出现不少种内存泄漏,想起以前面试时候这个问题也是考了不少次,一直没有总结,今天就趁机总结一下也好提醒本身平时多多注意。面试

什么是内存泄漏?

首先咱们得清楚什么是内存泄漏,在引擎中有垃圾回收机制,主要针对一些程序中再也不使用的对象,清理回收释放掉内存,可是实际上垃圾回收机制并不会把再也不使用的对象所有回收掉。所以咱们在代码中要主动避免一些不利于引擎作垃圾回收的操做,这些没有被及时回收的对象内存,咱们叫它内存泄漏(Memory Leak)小程序

常见的内存泄漏

来看看一些常见的内存泄漏案例:浏览器

不正当的闭包

大部分认为闭包就是函数内部嵌套并return一个函数,我翻了翻几本书中的描述:markdown

  • JavaScript高级程序设计:闭包是指有权访问另外一个函数做用域中的变量的函数。
  • JavaScript权威指南:从技术的角度讲,全部的JavaScript函数都是闭包,他们都是对象,都关联到做用域链。
  • 你不知道的JavaScript:当函数能够记住并访问所在的词法做用域时,就产生了闭包,即便函数是在当前词法做用域以外执行。

闭包涉及的范围是比较广了,如今看一个广泛的例子再认识一下闭包:闭包

function fnOne(){
  let test = new Array(1000).fill('www')
  return function(){
    console.log('hahaha')
  }
}
let fn1Child = fnOne()
fn1Child()
复制代码

这里由于return的函数中存在函数fnOne中的test变量引用,test不会被回收,也就形成了内存泄漏。app

怎么解决呢?就是在函数调用后,把外部的引用关系置空就行了:函数

function fnOne(){
  let test = new Array(1000).fill('www')
  return function(){
   console.log(test)
   return test
  }
}
let fn1Child = fnOne();
fn1Child()
fn1Child = null;
复制代码

减小使用闭包,不正当的使用闭包可能会形成内存泄漏。post

隐式全局变量

在JavaScript中,垃圾回收是自动执行的,可是对于全局变量,垃圾回收器很难判断这些变量何时才不被须要,因此全局变量不会被回收,这时候就产生了内存泄漏:测试

function fn(){
  // 没有声明从而制造了隐式全局变量test1
  test1 = new Array(1000).fill('isboyjc1')
  
  // 函数内部this指向window,制造了隐式全局变量test2
  this.test2 = new Array(1000).fill('isboyjc2')
}
fn()
复制代码

遗忘的定时器

let someResource = getData()
setInterval(() => {
  const node = document.getElementById('Node')
 if(node) {
    node.innerHTML = JSON.stringify(someResource))
 }
}, 1000)
复制代码

代码中,每隔一秒就把获得的数据放入到node节点中,可是在setInterval没有结束以前,回调函数里的变量以及回调函数自己都没法被回收。这时候须要用到clearInterval来清理这个定时器,才能回收someResource

setTiemout也是一样的道理,不须要时候,及时去清除。

遗忘的事件监听器

在代码中咱们会用到事件监听器,在组件内挂载相关的函数,组件销毁时候不主动清除时,其中的变量和函数会被认为是须要的,就不会被回收,这些内部引用的变量存储了大量数据,就会引发页面占用内存太高,形成内存泄漏。

遗忘的监听者模式

不论是Vue仍是React,监听者模式实现一些消息通讯是 很广泛的,好比EventBus,当咱们实现了监听者模式在组件内挂载相关的函数,组件销毁时候不主动清除,就一样不会进行回收。这时候咱们要在beforeDestroy 组件销毁生命周期里及时去清除。

未清理的Console输出

最后就是咱们在联调时候常见的console.log了,咱们在浏览器控制台能够看到数据输出,输出对象的时候就也形成了内存泄漏。

差很少说完了常见的内存泄漏,下一篇就讲一下怎么排查定位代码中是否存在内存泄漏

相关文章
相关标签/搜索