译者前言

  原文地址: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. 关于EditText的一点深入的了解

    最近在开发android下的记事本程序时,频繁的使用EditText控件,折腾来折腾去,算是对其的了解更深入了一些.特将这些收获记录如下: 一.几个属性的介绍 android:gravity=&quo ...

  2. Entity Framework中的Identity map和Unit of Work模式

    阅读目录: 一.什么是Identity map模式 二.关于Identity map模式的验证示例 三.Unit of Work 模式 四.总结和注意的问题 一,什么是Identity map模式 I ...

  3. Remoting和Webservice的区别

    其实现的原理并没有本质的区别,在应用开发层面上有以下区别:1.Remoting可以灵活的定义其所基于的协议,如果定义为HTTP,则与Web Service就没有什么区别了,一般都喜欢定义为TCP,这样 ...

  4. cxf 消息寻址

    一.消息寻址 WS-Addressing是将消息路由数据包含在SOAP头中的一种标准方法.利用WS-Addressing的消息可以在标准化的SOAP头中包含自己的包含发送元数据,而不是依赖于网络层传输 ...

  5. Spring学习笔记之 Spring IOC容器(一)之 实例化容器,创建JavaBean对象,控制Bean实例化,setter方式注入,依赖属性的注入,自动装配功能实现自动属性注入

    本节主要内容:       1.实例化Spring容器示例    2.利用Spring容器创建JavaBean对象    3.如何控制Bean实例化    4.利用Spring实现bean属性sett ...

  6. hdu 4607 Park Visit 求树的直径

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n) ...

  7. html弹窗半透明

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

  8. nginx如何设置访问跳转到一个固定页面

    方法一 server {    listen 80 ;    server_name  www.xxx.com xxx.com;      index   test.html  index.html ...

  9. 三星嵌入式开发平台 三星Cortex-A9 4412 POP与SCP对比

    iTOP-4412核心板是迅为电子推出的一款高端四核核心板,其中分为POP封装与SCP封装,配备三星Exynos 4412四核处理器,主频为1.4GHz,内置16GB存储空间.该板设计小巧.配备三星自 ...

  10. OpenXml 入门----OpenXml Tools使用技巧

    简介: Office2007以上版本的文档其实可以转换为XML格式.截图如下: Test.doc 解压过后已经完全变为文件夹和xml文件,文档的属性和信息都存储在了xml里面.根据XML就封装出了Op ...