加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

中高级前端必须了解的JS中的内存管理

发布时间:2019-07-05 05:13:31 所属栏目:建站 来源:王爷科技
导读:媒介 像C说话这样的底层说话一样平常都有底层的内存打点接口,好比 malloc()和free()用于分派内存和开释内存。 而对付JavaScript来说,会在建设变量(工具,字符串等)时分派内存,而且在不再行使它们时自动开释内存,这个自动开释内存的进程称为垃圾接纳。 由于

该工具包括四个字段,单元是字节,寄义如下:

  • rss(resident set size):全部内存占用,包罗指令区和仓库。
  • heapTotal:"堆"占用的内存,包罗用到的和没用到的。
  • heapUsed:用到的堆的部门。
  • external: V8 引擎内部的 C++ 工具占用的内存。

判定内存走漏,以heapUsed字段为准。

常见的内存泄漏案例

不测的全局变量

  1. function foo() { 
  2.  bar1 = 'some text'; // 没有声明变量 现实上是全局变量 => window.bar1 
  3.  this.bar2 = 'some text' // 全局变量 => window.bar2 
  4. foo(); 

在这个例子中,不测的建设了两个全局变量 bar1 和 bar2

被忘记的按时器和回调函数

在许多库中, 假如行使了调查者模式, 城市提供回调要领, 来挪用一些回调函数。

要记得接纳这些回调函数。举一个 setInterval的例子:

  1. var serverData = loadData(); 
  2. setInterval(function() { 
  3.  var renderer = document.getElementById('renderer'); 
  4.  if(renderer) { 
  5.  renderer.innerHTML = JSON.stringify(serverData); 
  6.  } 
  7. }, 5000); // 每 5 秒挪用一次 

假如后续 renderer 元素被移除,整个按时器现实上没有任何浸染。

但假如你没有接纳按时器,整个按时器依然有用, 不单按时器无法被内存接纳,

按时器函数中的依靠也无法接纳。在这个案例中的 serverData 也无法被接纳。

闭包

在 JS 开拓中,我们会常常用到闭包,一个内部函数,有权会见包括其的外部函数中的变量。

下面这种环境下,闭包也会造成内存泄漏:

  1. var theThing = null; 
  2. var replaceThing = function () { 
  3.  var originalThing = theThing; 
  4.  var unused = function () { 
  5.  if (originalThing) // 对付 'originalThing'的引用 
  6.  console.log("hi"); 
  7.  }; 
  8.  theThing = { 
  9.  longStr: new Array(1000000).join('*'), 
  10.  someMethod: function () { 
  11.  console.log("message"); 
  12.  } 
  13.  }; 
  14. }; 
  15. setInterval(replaceThing, 1000); 

这段代码,每次挪用 replaceThing 时,theThing 得到了包括一个庞大的数组和一个对付新闭包 someMethod 的工具。

同时 unused 是一个引用了 originalThing 的闭包。

这个典型的要害在于,闭包之间是共享浸染域的,尽量 unused 也许一向没有被挪用,可是 someMethod 也许会被挪用,就会导致无法对其内存举办接纳。

当这段代码被重复执行时,内存会一连增添。

DOM 引用

许多时辰, 我们对 Dom 的操纵, 会把 Dom 的引用生涯在一个数组可能 Map 中。

  1. var elements = { 
  2.  image: document.getElementById('image') 
  3. }; 
  4. function doStuff() { 
  5.  elements.image.src = 'http://example.com/image_name.png'; 
  6. function removeImage() { 
  7.  document.body.removeChild(document.getElementById('image')); 
  8.  // 这个时辰我们对付 #image 如故有一个引用, Image 元素, 如故无法被内存接纳. 

上述案例中,纵然我们对付 image 元素举办了移除,可是如故有对 image 元素的引用,依然无法对齐举办内存接纳。

其它必要留意的一个点是,对付一个 Dom 树的叶子节点的引用。

举个例子: 假如我们引用了一个表格中的td元素,一旦在 Dom 中删除了整个表格,我们直观的认为内存接纳应该接纳除了被引用的 td 外的其他元素。

可是究竟上,这个 td 元素是整个表格的一个子元素,并保存对付其父元素的引用。

这就会导致对付整个表格,都无法举办内存接纳。以是我们要警惕处理赏罚对付 Dom 元素的引用。

怎样停止内存走漏

记着一个原则:不消的对象,实时偿还。

  1. 镌汰不须要的全局变量,行使严酷模式停止不测建设全局变量。
  2. 在你行使完数据后,实时扫除引用(闭包中的变量,dom引用,按时器破除)。
  3. 组织好你的逻辑,停止死轮回等造成赏识器卡顿,瓦解的题目。

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读