译者前言

  原文地址:Memory leaks  

  最近简单了解了下JavaScript的闭包和垃圾回收机制(GC),这中间也不得不接触内存泄露这个概念。然后不小心找到了这篇文章,看下来后理解了不少东西,于是译之与大家分享。

  在JavaScript中,我们很少考虑到内存管理,但是它又是真实存在的。当我们创建一个变量,接着使用它们,然后浏览器的垃圾回收机制对它们进行回收。

  虽然我们很少考虑内存管理,但是当应用程序越来越复杂并且ajax化之后,我们打开一个网页,过段时间发现浏览器消耗的内存不断增大,很有可能是因为内存泄露,这时我们不得不考虑内存管理。

JavaScript的内存管理

  JavaScript内存管理的核心也就是JavaScript垃圾回收机制,而存在在内存中的数据包括堆栈中的数据(局部变量,正在被调用的方法的参数)以及全局变量;而对象如果被引用或者存在在一个引用链中时,也会存在在内存中。关于这点可以参考JavaScript垃圾回收机制。

  下面再举个GC的例子:

function Menu(title) {
  this.title = title
  this.elem = document.getElementById('id')
}

var menu = new Menu('My Menu')

document.body.innerHTML = ''  // (1)

menu = new Menu('His menu') // (2)

  内存结构如下:

  在step(1)后,body.innerHTML被清空了,所以它的子节点都被移除了。但是元素#id是个例外,它依然能通过menu.elem访问,所以它依然存在在内存中,当然如果你无法访问它的父节点,因为它被移除了。

  单个的dom元素可能存在在内存中哪怕它的父节点已经被移除。

  在step(2)后,window.menu被重新赋值引用,所以原来的menu不可访问了,于是自动被GC回收。

  而闭包经常会引起循环引用:

function setHandler() {

  var elem = document.getElementById('id')

  elem.onclick = function() {
    // ...
  }

}

  dom元素elem通过onclick引用了一个function,而这个function内部也能引用外部作用域里的dom变量elem。

  甚至onclick函数里没有代码,该循环引用同样成立。而一些像addEventListener/attachEvent的方法也会形成类似的循环引用。

内存泄露

  当一个对象不再被引用,但是浏览器由于某些原因并没有释放内存,这时就会引起内存泄露。浏览器问题,浏览器的插件问题,或者我们自己的代码问题都可能引起内存泄露。

  在前面垃圾回收机制一文中我们了解,在IE8以下时,dom对象的循环引用就会引起内存泄露(更进一步讲,其实是COM对象)

function setHandler() {
  var elem = document.getElementById('id')
  elem.onclick = function() { /* ... */ }
}

  dom对象外,任何的COM对象包括XMLHttpRequest都会引起内存泄露。

  IE的内存泄露的解决方式是打破循环引用。

  我们把dom元素elem赋值为null,所以onclick里的function不会再引用elem,所以这个循环被打破了。

  关于XmlHttpRequest的内存管理和泄露:

  以下的代码在IE9以下完美泄露...

var xhr = new XMLHttpRequest() // or ActiveX in older IE

xhr.open('GET', '/server.url', true)

xhr.onreadystatechange = function() {
  if(xhr.readyState == 4 && xhr.status == 200) {
    // ...
  }
}

xhr.send(null)

  让我们来看看内存树:

  

  • JQuery中针对内存泄露的措施以及新的泄露

  jQuery这块还没仔细研究过,略...

  在chrome开发者工具栏中,有个timeline,能或多或少检测内存泄露。

(译)JavaScript内存泄露的更多相关文章

  1. 4类 JavaScript 内存泄露及如何避免

    原文:4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them笔记:涂鸦码龙 译者注:本文并没有逐字逐句的翻译,而是把我认为重要 ...

  2. JavaScript内存泄露,闭包内存泄露如何解决

    本文原链接:https://cloud.tencent.com/developer/article/1340979 JavaScript 内存泄露的4种方式及如何避免 简介 什么是内存泄露? Java ...

  3. [ Javascript ] 内存泄露以及循环引用解析

    内存泄露 在javascript中,我们非常少去关注内存的管理. 我们创建变量,使用变量,浏览器关注这些底层的细节都显得非常正常. 可是当应用程序变得越来越复杂而且ajax化之后,或者用户在一个页面停 ...

  4. 常见的几种JavaScript内存泄露

    总结一下常见的几种JavaScript内存泄露: 1.意外的全局变量 全局变量属于window对象,所以只会随着window销毁才会销毁. 2.console.log() conaole.log()函 ...

  5. Javascript内存泄露

    在过去一些的时候,Web开发人员并没有太多的去关注内存泄露问题.那时的页面间联系大都比较简单,并主要使用不同的连接地址在同一个站点中导航,这样的设计方式是非常有利于浏览器释放资源的.即使Web页面运行 ...

  6. 【翻译】JavaScript内存泄露

    原文地址:http://javascript.info/tutorial/memory-leaks#tools 我们在进行JavaScript开发时,很少会考虑内存的管理.JavaScript中变量的 ...

  7. [转]常见的JavaScript内存泄露

    什么是内存泄露 内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存.内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制, ...

  8. JavaScript 内存泄露以及如何处理

    一.前言 一直有打算总结一下JS内存泄露的方面的知识的想法,但是总是懒得提笔. 富兰克林曾经说过:懒惰,像生鏽一样,比操劳更能消耗身体,经常用的钥匙总是亮闪闪的.安利一下,先起个头. 二.内存声明周期 ...

  9. 常见的 JavaScript 内存泄露

    什么是内存泄露 指由于疏忽或错误造成程序未能释放已经不再使用的内存.内存泄漏并非指内存在物理上的消失, 而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造 ...

随机推荐

  1. javascript元素绑定事件

    js元素绑定事件   想给一个元素绑定一个方法之后,在绑定一个方法而且不被覆盖 window.onload = function () { alert('a'); } window.onlaod=fu ...

  2. 软件测试作业3--Junit、hamcrest、eclemmat的安装和使用

    1.   how to install junit, hamcrest and eclemma? 首先下载下来Junit和Hamcrest的jar包,然后新建项目的时候将这两个jar包导入到工程里面就 ...

  3. SQLServerDBA十大必备工具---让生活轻松点(转)

    曾经和一些DBA和数据库开发人员交流时,问他们都用过一些什么样的DB方面的工具,大部分人除了SSMS和Profile之外,基本就没有使用过其他工具了: 诚然,SSMS和Profile足够强大,工作的大 ...

  4. matchesSelector及低版本IE中对该方法的实现

    matchesSelector用来匹配dom元素是否匹配某css selector.它为一些高级方法的实现提供了基础支持,比如事件代理,parent, closest等. W3C在2006年就提出了该 ...

  5. centos6.7 安装Docker

      一.查看系统版本 [root@localhost ~]# cat /etc/redhat-release CentOS release 6.7 (Final) 二.安装EPEL 1.进入cento ...

  6. openfire+asmack搭建的安卓即时通讯(四) 15.4.10

    之前的教程不知道你们成功了没,,,没成功可以问我啊=-= 第四篇博文是要实现发送消息的功能. 首先在我们登陆后的活动的layout里添加这样的两个控件,一个EditText和一个Button用于发送数 ...

  7. Maxwell’s Equations

    A=cos(pi*x-pi/2)i+sin(pi*x)j 正电荷形成的电场 负电荷形成的电场   正负电荷形成的电场 无限长导线上均匀分布的正电荷 电场 均匀分布电荷的平面 电场 电荷均匀分布的球面形 ...

  8. 【ASP.NET 类库】当你懒得用 Json+Ajax 时,可以试试 AjaxPro

    一般我们在页面调用Ajax时,需要通过 js 调用ajax ,接着后台处理得到的数据,然后返回数据,ajax 得到返回的数据进行处理. 然而有没有可以像调用方法一样来进行Ajax操作呢? AjaxPr ...

  9. [翻译]为你的服务器选择正确的.NET

    英文原文 By Daniel Roth ASP.NET 5 is based on the .NET Execution Environment (DNX), which supports runni ...

  10. CSS强制性换行word-break与word-wrap的使用

    一般情况下,元素拥有默认的white-space:normal(自动换行,不换行是white-space:nowrap),当录入的文字超过定义的宽度后会自动换行,但当录入的数据是一堆没有空格的字符或字 ...