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

一、什么是内存泄露

内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。在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内存泄露的几种情况

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

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

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

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

    转载于http://blog.csdn.net/wtt945482445/article/details/52483944 Java 内存分配策略 Java 程序运行时的内存分配策略有三种,分别是静态 ...

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

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

  5. C++中内存泄漏的几种情况

    1. 在类的构造函数和析构函数中没有匹配的调用new和delete函数 两种情况下会出现这种内存泄露:一是在堆里创建了对象占用了内存,但是没有显示地释放对象占用的内存:二是在类的构造函数中动态的分配了 ...

  6. C++内存泄漏的几种情况

    1. 在类的构造函数和析构函数中没有匹配的调用new和delete函数 两种情况下会出现这种内存泄露:一是在堆里创建了对象占用了内存,但是没有显示地释放对象占用的内存:二是在类的构造函数中动态的分配了 ...

  7. Java内存泄漏的几种可能

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

  8. Chrome JS内存泄漏排查方法(Chrome Profiles)

     原文网址:http://blog.csdn.net/kaitiren/article/details/19974269 JS内存泄漏排查方法(Chrome Profiles)   Google Ch ...

  9. JS内存泄漏 和Chrome 内存分析工具简介(摘)

    原文地址:http://web.jobbole.com/88463/ JavaScript 中 4 种常见的内存泄露陷阱   原文:Sebastián Peyrott 译文:伯乐在线专栏作者 - AR ...

随机推荐

  1. 和Webbrowser进行简单交互

    作为第一篇,简单的控件使用就不说了. 直接从简单的交互开始吧! C#使用网页中已有的js函数 webBrowser.Document.InvokeScript("Stop");// ...

  2. 第七篇 Python面向对象

    类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用,特征被称为属性,行为被称为方法,类就相当于制造飞机时的图纸,是一个模板,是负责创建对象的. 对象是由类创建出来的一个具体存在,可 ...

  3. django中博客后台将图片上传作为用户头像

    添加上传目录 # 如果不添加上传目录,仍然可以上传成功,默认为project目录,如果models.py定义了upload_to="目录名称",则会上传到"project ...

  4. ASPxGridView编辑时弹出的editform值不是当前行值的原因

    如下图所示(左边是红框是ASPxGridView编辑的行,右边是弹出的editform上显示的值). 这是因为ASPxGridView的KeyFieldName的值不是唯一的,需要修改或增加条件使键值 ...

  5. 使用C语言封装数组,动态实现增删改查

    myArray.h : #pragma once //包含的时候只包含一次 #include <stdio.h> #include <stdlib.h> #include &l ...

  6. C#/ASP.NET对URL中的中文乱码处理

    前言:UTF-8中,一个汉字对应三个字节,GB2312中一个汉字占用两个字节. 不论何种编码,字母数字都不编码,特殊符号编码后占用一个字节. 1.直接在C#后台编码URL参数 引用类库:System. ...

  7. zbar

    源码下载链接:http://sourceforge.net/projects/zbar

  8. 25.Remove Nth Node From End of List(删除链表的倒数第n个节点)

    Level:   Medium 题目描述: Given a linked list, remove the n-th node from the end of list and return its ...

  9. 洛谷 P1546 最短网络 Agri-Net(最小生成树)

    嗯... 题目链接:https://www.luogu.org/problemnew/show/P1546 首先不难看出这道题的思想是用了最小生成树,但是这道题有难点: 1.读题读不明白 2.不会读入 ...

  10. Java 实现邮件的发送

                                             Java 实现邮件的发送 开发邮箱发送功能必须看邮箱方面的资料 改一些东西  (我的是qq 邮箱哟   开通 POP3 ...