博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(译)JavaScript内存泄露
阅读量:7105 次
发布时间:2019-06-28

本文共 1858 字,大约阅读时间需要 6 分钟。

译者前言

  原文地址:

  最近简单了解了下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 IExhr.open('GET', '/server.url', true)xhr.onreadystatechange = function() {  if(xhr.readyState == 4 && xhr.status == 200) {                // ...  }}xhr.send(null)

  让我们来看看内存树:

  

 

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

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

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

转载地址:http://qophl.baihongyu.com/

你可能感兴趣的文章
mrjob报语法错误
查看>>
解决PXE批量网络安装Linux系统时kickstart自动识别硬盘名称的问题的方案
查看>>
JVM调优实战
查看>>
前端资源(4)
查看>>
开启多台GuestOS提示无loop设备可用
查看>>
PHP编写一些检查项函数
查看>>
笨鸟先飞学编程系列之二 基础代码的编写2(转)
查看>>
samza快速理解
查看>>
spark streaming容错机制
查看>>
空间和数据库存储的区别是什么
查看>>
我的友情链接
查看>>
新站不带www域名显露出来当天快照
查看>>
[图灵程序设计丛书].高效算法:竞赛、应试与提高必修128例.pdf
查看>>
二叉树的实现及其可视化
查看>>
Android流行样式书签
查看>>
Servlet详解
查看>>
Ext 表单与输入控件 下拉框
查看>>
CentOS 6 启动流程
查看>>
第二个python爬虫 多页面抓取美女图片
查看>>
jpa多数据源配置参考链接
查看>>