译者前言

  原文地址: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. 【转载】改善数据质量从数据剖析(Data Profiling)开始

    市场研究公司Forrester副总裁Erin Kinikin曾经把低劣的数据质量做了一个形象的比喻“用更好的方法访问劣质的数据,结果类似于把已经腐烂了的桃子用更快的卡车,走更好的路线运输到达市场时,桃 ...

  2. Hibernate之Criteria的完整用法

    Criteria的完整用法 QBE (Query By Example) Criteria cri = session.createCriteria(Student.class); cri.add(E ...

  3. cocos2d-x之事件传递

    bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size size=Director::getInstance()- ...

  4. cocos2d-x之场景转换特效

    bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getIn ...

  5. linux 截图利器-scrot

    一.前言 linux下截图工具有很多,scrot无疑是众多工具中的一个亮点,下面记录下其安装配置过程 二.使用环境 操作系统: centos 6.2 三.依赖 scrot依赖 giblib, gibl ...

  6. [转]10个学习Android开发的网站推荐

    本文转自:http://blog.csdn.net/i_lovefish/article/details/43950893 1. Android Developers 作为一个Android开发者,官 ...

  7. NOIP2007 T2纪念品分组 解题报告-S.B.S.

    #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #inclu ...

  8. 【ASP.NET 进阶】定时执行任务

    原理:利用全局应用程序类 Global.asax 和 System.Timers.Timer  类定时处理任务. 示例效果图: 其 Global.asax 类代码如下: using System; u ...

  9. 分享十二个有用的jQuery代码

    分享7个有用的jQuery代码 这篇文章主要介绍了7个有用的jQuery技巧分享,本文给出了在新窗口打开链接.设置等高的列.jQuery预加载图像.禁用鼠标右键.设定计时器等实用代码片段,需要的朋友可 ...

  10. spring加载xml

    加载文件顺序 情形一:使用classpath加载且不含通配符 这是最简单的情形,Spring默认会使用当前线程的ClassLoader的getResource方法获取资源的URL,如果无法获得当前线程 ...