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

一、什么是内存泄露

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

二、内存泄露的几种情况

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

  1. <div id="myDiv">
  2. <input type="button" value="Click me" id="myBtn">
  3. </div>
  4. <script type="text/javascript">
  5. var btn = document.getElementById("myBtn");
  6. btn.onclick = function(){
  7. document.getElementById("myDiv").innerHTML = "Processing...";
  8. }
  9. </script>

应改成下面

  1. <div id="myDiv">
  2. <input type="button" value="Click me" id="myBtn">
  3. </div>
  4. <script type="text/javascript">
  5. var btn = document.getElementById("myBtn");
  6. btn.onclick = function(){
  7. btn.onclick = null;
  8. document.getElementById("myDiv").innerHTML = "Processing...";
  9. }
  10. </script>

或者采用事件委托

  1. <div id="myDiv">
  2. <input type="button" value="Click me" id="myBtn">
  3. </div>
  4. <script type="text/javascript">
  5. document.onclick = function(event){
  6. event = event || window.event;
  7. if(event.target.id == "myBtn"){
  8. document.getElementById("myDiv").innerHTML = "Processing...";
  9. }
  10. }
  11. </script>

2、

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

  1. var a=document.getElementById("xx");
  2. a.r=a;

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

3、

  1. function bindEvent()
  2. {
  3. var obj=document.createElement("XXX");
  4. obj.onclick=function(){
  5. //Even if it's a empty function
  6. }
  7. }
闭包可以维持函数内局部变量,使其得不到释放。
上例定义事件回调时,由于是函数内定义函数,并且内部函数--事件回调的引用外暴了,形成了闭包
解决之道,将事件处理函数定义在外部,解除闭包
  1. function bindEvent()
  2. {
  3. var obj=document.createElement("XXX");
  4. obj.onclick=onclickHandler;
  5. }
  6. function onclickHandler(){
  7. //do something
  8. }

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

  1. function bindEvent()
  2. {
  3. var obj=document.createElement("XXX");
  4. obj.onclick=function(){
  5. //Even if it's a empty function
  6. }
  7. obj=null;
  8. }

4、

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

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

5. 自动类型装箱转换

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

  1. var s=”lalala”;
  2.  
  3. alert(s.length);

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

  1. var s="lalala";
  2.  
  3. 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. windows下安装newman

    1.下载安装node.js,下载地址::https://nodejs.org/en/download/,这里我下载的为v10.15.0-x64.msi,下载后直接安装即可,安装完后可输入node -v ...

  2. C#质因子(自己别扭的逻辑。。)

    static int length1(int num) //想着要定义一个函数取,质因子数组的长度 { ; ; i <= num; i++) //for循环中I 不会归零 只能遍历一次 { if ...

  3. 连接数据库+注册->登录->抽奖(有关联关系的接口)

    注册账号信息需要写入数据库,登录和抽奖时从数据库获取数据 一.连接数据库 my_sql.py: import pymysql class MyDb: def __init__(self,host,pa ...

  4. 51nod1228 序列求和(伯努利数)

    题面 传送门 题解 \(O(n^2)\)预处理伯努利数 不知道伯努利数是什么的可以看看这篇文章 不过这个数据范围拉格朗日差值应该也没问题--吧--大概-- //minamoto #include< ...

  5. python基础之格式化字符串

    一.格式化字符功能介绍 应用场景:一般在print的时候提供占位符;python中提供两种格式化字符串方式:第一种是古老的利用百分号的方式,第二种是增强的格式化字符串.format 函数. 二.古老的 ...

  6. 使用github和hexo搭建静态博客

    获得更多资料欢迎进入我的网站或者 csdn或者博客园 终于写这篇文章了,这是我使用github和hexo搭建博客的一些心得,希望能给大家一点帮助.少走点弯路.刚接触github,只是用来存项目的版本, ...

  7. 【智能算法】变邻域搜索算法(Variable Neighborhood Search,VNS)超详细解析和TSP代码实例以及01背包代码实例

    喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 00 目录 局部搜索再次科普 变邻域搜索 造轮子写代码 01 局部搜索科普三连 虽然之前做的很多篇启发式的算法都有跟大家提过局部 ...

  8. SDUT OJ 效率至上(线段树)

    效率至上 Time Limit: 5000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 题意很简单,给出一个数目为n ...

  9. 将form转为ajax提交的js代码

    参考网络代码基础上进行修改,调试通过. 在html中插入下面的代码: 函数ajaxSubmit是submit的ajax形式. 注意:这里面使用到了jquery库 //<!--将form中的值转换 ...

  10. 按钮重复点击问题 UIbutton

    .h #import <UIKit/UIKit.h> #import <objc/runtime.h> @interface UIControl (XY) @property ...