想解决内存泄露问题,必须知道什么是内存泄露,什么情况下出现内存泄露,才能在遇到问题时,逐个排除。这里只讨论那些不经意间的内存泄露。

一、什么是内存泄露

内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。在C++中,因为是手动管理内存,内存泄露是经常出现的事情。而现在流行的C#和Java等语言采用了自动垃圾回收方法管理内存,正常使用的情况下几乎不会发生内存泄露。浏览器中也是采用自动垃圾回收方法管理内存,但由于浏览器垃圾回收方法有bug,会产生内存泄露。

二、内存泄露的几种情况

1、当页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会作出恰当处理,此时要先手工移除事件,不然会存在内存泄露。

 <div id="myDiv">
<input type="button" value="Click me" id="myBtn">
</div>
<script type="text/javascript">
var btn = document.getElementById("myBtn");
btn.onclick = function(){
document.getElementById("myDiv").innerHTML = "Processing...";
}
</script>

应改成下面

 <div id="myDiv">
<input type="button" value="Click me" id="myBtn">
</div>
<script type="text/javascript">
var btn = document.getElementById("myBtn");
btn.onclick = function(){
btn.onclick = null;
document.getElementById("myDiv").innerHTML = "Processing...";
}
</script>

或者采用事件委托

 <div id="myDiv">
<input type="button" value="Click me" id="myBtn">
</div>
<script type="text/javascript">
document.onclick = function(event){
event = event || window.event;
if(event.target.id == "myBtn"){
document.getElementById("myDiv").innerHTML = "Processing...";
}
}
</script>

2、

 var a=document.getElementById("xx");
var b=document.getElementById("xxx");
a.r=b;
b.r=a;
 var a=document.getElementById("xx");
a.r=a;

对于纯粹的 ECMAScript 对象而言,只要没有其他对象引用对象 a、b,也就是说它们只是相互之间的引用,那么仍然会被垃圾收集系统识别并处理。但是,在 Internet Explorer 中,如果循环引用中的任何对象是 DOM 节点或者 ActiveX 对象,垃圾收集系统则不会发现它们之间的循环关系与系统中的其他对象是隔离的并释放它们。最终它们将被保留在内存中,直到浏览器关闭。

3、

 function bindEvent()
{
var obj=document.createElement("XXX");
obj.onclick=function(){
//Even if it's a empty function
}
}

闭包可以维持函数内局部变量,使其得不到释放。

上例定义事件回调时,由于是函数内定义函数,并且内部函数--事件回调的引用外暴了,形成了闭包
解决之道,将事件处理函数定义在外部,解除闭包

 function bindEvent()
{
var obj=document.createElement("XXX");
obj.onclick=onclickHandler;
}
function onclickHandler(){
//do something
}

或者在定义事件处理函数的外部函数中,删除对dom的引用(题外,《JavaScript权威指南》中介绍过,闭包中,作用域中没用的属性可以删除,以减少内存消耗。)

 function bindEvent()
{
var obj=document.createElement("XXX");
obj.onclick=function(){
//Even if it's a empty function
}
obj=null;
}

4、

 a = {p: {x: 1}};
b = a.p;
delete a.p;

执行这段代码之后b.x的值依然是1.由于已经删除的属性引用依然存在,因此在JavaScript的某些实现中,可能因为这种不严谨的代码而造成内存泄露。所以在销毁对象的时候,要遍历属性中属性,依次删除。

5. 自动类型装箱转换

看网上资料,说下面的代码在ie系列中会导致内存泄露,先提个神,具体泄露与否先不管

 var s=”lalala”;
alert(s.length);

s本身是一个string而非object,它没有length属性,所以当访问length时,JS引擎会自动创建一个临时String对象封装s,而这个对象一定会泄露。这个bug匪夷所思,所幸解决起来相当容易,记得所有值类型做.运算之前先显式转换一下:

 var s="lalala";
alert(new String(s).length);

6、某些DOM操作

IE系列的特有问题 简单的来说就是在向不在DOM树上的DOM元素appendChild;IE7中,貌似为了改善内存泄露,IE7采用了极端的解决方案:离开页面时回收所有DOM树上的元素,其它一概不管。

本文首发: http://www.cnblogs.com/sprying/archive/2013/05/31/3109517.html

以上知识点来源于《JavaScript高级程序设计》和《JavaScript权威指南》和 http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html#clSto

http://www.uml.org.cn/site/201205294.asp

《JavaScript高级程序设计》有关内存部分http://bbs.phpchina.com/thread-221214-1-1.html

待收录 http://www.feeldesignstudio.com/2013/09/javascript-memory-management

js内存泄露的几种情况的更多相关文章

  1. js内存泄露的几种情况详细探讨

    内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束.在C++中,因为是手动管理内存,内存泄露是经常出现的事情.而现在流行的C#和Java等语言采用了自动垃圾回收方法管理内存,正常使 ...

  2. Js内存泄漏的几种情况

    想解决内存泄露问题,必须知道什么是内存泄露,什么情况下出现内存泄露,才能在遇到问题时,逐个排除.这里只讨论那些不经意间的内存泄露. 一.什么是内存泄露 内存泄露是指一块被分配的内存既不能使用,又不能回 ...

  3. java 内存泄露的几种情况

    内存泄漏定义(memory leak):一个不再被程序使用的对象或变量还在内存中占有存储空间. 一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出.内存溢出 out of memory ...

  4. 浅析造成 JS 内存泄露的几种原因及解决方案

    内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束.在C++中,因为是手动管理内存,内存泄露是经常出现的事情.而现在流行的C#和Java等语言采用了自动垃圾回收方法管理内存,正常使 ...

  5. Js内存泄露问题总结

    最近接受了一个Js职位的面试,问了很多Js的高级特性,才发现长时间使用已知的特性进行开发而忽略了对这门语言循序渐进的理解,包括Java我想也是一样,偶尔在Sun官方看到JDK6.0列举出来的new f ...

  6. Java中的内存泄露的几种可能

    Java内存泄漏引起的原因: 内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏. 长生命周期的对象持有短生命周期对象的引用就很可能发 ...

  7. JS内存泄露常见原因

    详细内容请点击 分享的笔记本-前端 开发中,我们常遇见的一些关于js内存泄露的问题,有时候我们常常会找半天找不出原因,这里给大家介绍简单便捷的方法 1.闭包上下文绑定后没有释放:   2.观察者模式在 ...

  8. js造成内存泄漏的几种情况

    1.介绍js的垃圾回收机制 js的垃圾回收机制就是为了防止内存泄漏的,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的 ...

  9. javascript js 内存泄露

    JavaScript 内存泄露 1.什么是闭包.以及闭包所涉及的作用域链这里就不说了. 2.JavaScript垃圾回收机制 JavaScript不需要手动地释放内存,它使用一种自动垃圾回收机制(ga ...

随机推荐

  1. [网络技术][转]网卡的offload概念

    网络数据包分析 网卡Offload 对于网络安全来说,网络传输数据包的捕获和分析是个基础工作,绿盟科技研究员在日常工作中,经常会捕获到一些大小远大于MTU值的数据包,经过分析这些大包的特性,发现和网卡 ...

  2. C++Primer 一

    1.vertor和数组的区别: 数组的长度固定.而且程序是无法知道一个给定数组的长度,数组没有获取器容量大小的size操作,也不提供puch_back操作在其中自动添加元素 2.数组定义中的类型可以示 ...

  3. SQL Server 在数据库中查找字符串(不知道表名的情况下 查找字符串)

    declare @key varchar(30)set @key = '广州' --替换为要查找的字符串DECLARE @tabName VARCHAR(40),@colName VARCHAR(40 ...

  4. JAVA开发相关

    JAVA开发相关1. IntelliJ IDEA开发工具熟练使用2. Maven3. Spring框架(IoC.AOP) 1)数据库相关MyBatis 2)数据库连接池 3)事务.多数据源.跨数据库分 ...

  5. FreeCAD鼠标操作指南

    鼠标控制模式 跳转至: 导航. 搜索 freeCAD鼠标的控制模式由多个命令构成,用于三维空间的视觉导航和控制显示对象.freecad支持多个鼠标导航方式.默认的导航方式是被称为“CAD导航”,非常简 ...

  6. Android Design Support Library使用详解

    Android Design Support Library使用详解 Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的And ...

  7. mariadb配置允许远程访问方式

    首先配置允许访问的用户,采用授权的方式给用户权限 1 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY '123456' WITH GRAN ...

  8. iOS中修改头部tabBarButton 默认按钮的颜色和默认字体颜色

    +(void)initialize { //初始化设置主题 UINavigationBar *navBar = [UINavigationBar appearance]; [navBar setBac ...

  9. Jqgrid学习API

    JQGrid是一个在jquery基础上做的一个表格控件,以ajax的方式和服务器端通信. JQGrid Demo 是一个在线的演示项目.在这里,可以知道jqgrid可以做什么事情. 下面是转自其他人b ...

  10. EntityFrameworkCore 试用

    引用 EF Core Sqlite Install-Package Microsoft.EntityFrameworkCore.SqlServer 引用 EF Core Tool Install-Pa ...