美文网首页
javascript内存泄露及解决方案详解

javascript内存泄露及解决方案详解

作者: 铁木真丫丫丫 | 来源:发表于2017-06-02 22:24 被阅读60次
一、常见的内存泄露类型

1.造成内存泄露的代码:
(1)循环引用
(2)自动类型装箱转换
(3)某些DOM 操作

2.循环引用

著名循环引用的例子(IE6,FF2):

function A(){
  var a=document.createElement("div");
  a.onclick=function(){
     alert("hi");
  }
}
A();

假设A()执行时创建的作用域对象叫做ScopeA,那么有以下引用关系:

ScopeA 引用了DOM对象a,DOM对象引用匿名函数,匿名函数引用ScopeA。

3.自动类型装箱转换(IE6,IE7)

var s="hhhhh";
alert(s.length);

"hhhhh"已经泄露了,关键问题出在s.length上,在js类型中,String类型并非对象,但是可以可以使用(.)运算符,因为js的默认类型转换机制,允许js在遇到(.)运算符时,自动将string类型转换为Object中对应的String对象。该临时转换的对象100%会泄露。

4.某些DOM操作会导致内存泄露(IE)

  function leakMemory(){
        var  i=0,//
               parentDiv,//
               childDiv,//
               doc=document,//
               element=document.getElementById("element");
        for( ;i<5000;i++ ){
            parentDiv=doc.createElement("<div onClick='foo()'>");
          
           childDiv=document.createElement("<div onClick='foo()'>");
         
           parentDiv.appendChild(childDiv);
           element.appendChild(parentDiv);
           
           element.removeChild(parentDiv);
           parentDiv.removeChild(childDiv);

           parentDiv=null;
           childDiv=null;
           }
           element=null;
      }

leakMemory 造成了内存泄露,MS的解释是,擦好人的顺序不对,必须先将父级元素appendChild。

在IE7和IE8下运行,内存泄露,但是刷新下页面就好了,IE7改变了DOM元素的回收方式,在离开页面时,回收DOM树上的所有元素。所以,IE7下内存管理非常简单,在所有页面中,只要挂在DOM树上的元素,就不会泄露,没挂在DOM树上的元素,肯定泄露。所以,IE7下,记住一条原则,在离开页面前,把所有的DOM元素挂到DOM树上。

IE的这种做法是偷懒做法:动态垃圾回收不是保证所有的内存都在离开页面时回收,而是保证内存的充分利用。运行时不回收,IE只是名义上避免内存泄露,实际上是完全的泄露。

二、内存泄露的解决方案

1.显示类型转换

对于类型转换的错误,我们可以通过显示类型转换的方式来避免。

  var str=new String("hhhhhh");
  alert(str.length);

2.避免事件导致的循环引用。

 function A(){
     var a=document.createElement("div");
     var b=document.createElement("div");

     a.onclick=function(){
        alert(b.outerHTML);
     }
     return a;
 }

一般情况下,就把函数放在外面或者a=null 没问题了,但是,访问A()里面的变量的话,要另做分析。上面的例子,把a的事件函数放在外面就不能访问A()里面的对象b。如果要返回a的值,a就不能为null。

解决方案一:

 function A(){

     var a=document.createElement("div");

     var b=document.createElement("div");

     a.onclick=BulidEvent(b);

      return a;
 }

function BuildEvent(b){
  return function(){
     alert(b.outerHTML);
  }
 }

解决方案2:

在return 之后 a=null;

 function A(){
    try{
       var a=document.createElement("div");
       var b=document.createElement("div");

        a.onclick=function(){
        alert(b.outerHTML);
     }
        return a;
     }finally{
        a=null;
     }
  }

3.垃圾箱

IE下,DOM对象不会被CG程序回收,只有在离开页面时才会被回收。一旦使用了DOM对象,千万不要试图o=null,可以设置一个叫garbage 的div,并且将其display设置为none,将不用的DOM对象存入其中。

三、内存泄露的一些疑问

1、内存泄露是内存占用很大吗?
不是,即使是1byte的内存,也叫内存泄露。

2、程序中提示内存不足,是内存泄露吗?
不是,着一般是无限递归函数调用,导致栈内存溢出。

3.内存泄露是哪个区域?

堆区。栈区不会泄露

4.window对象时DOM对象吗?

不是,window对象参与的循环引用是不会内存泄露。

5.内存泄露的后果?

大多数情况下,后果不是很严重。但是过多的DOM操作会使网页执行速度变慢。

6.跳转网页,内存泄露仍然存在吗?

仍然存在,直到浏览器关闭。

相关文章

  • javascript内存泄露及解决方案详解

    一、常见的内存泄露类型 1.造成内存泄露的代码:(1)循环引用(2)自动类型装箱转换(3)某些DOM 操作 2.循...

  • 内存泄露系列文章(一) - 内存泄露原因及影响

    前言 内存泄露系列文章内存泄露系列文章(一) - 内存泄露原因及影响内存泄露系列文章(二) - 内存泄露监测及分析...

  • 内存泄露系列文章(三) - 内存泄露解决方案

    前言 内存泄露系列文章内存泄露系列文章(一) - 内存泄露原因及影响内存泄露系列文章(二) - 内存泄露监测及分析...

  • Android使用Handler造成内存泄露的分析及解决方法

    阅读目录 一、什么是内存泄露? 二、内存泄露的危害 三、解决方案 四、总结 一、什么是内存泄露? Java使用有向...

  • 内存泄露常见情况

    ThreadLocal 引起的内存泄露 解决方案 线程未取消引用的内存泄露 1,viewpager自动滚动+手动滚...

  • Android内存泄露详解

    内存泄露 在开发应用的过程中,我们总会遇到内存泄露的问题。现在通过代码列出一些常见的内存泄露的情况以及解决方案。 ...

  • 性能优化

    1,通过leak查看是否有内存泄露,(发现afn导致的内存泄露,原因,AFNManager对象多次创建,解决方案,...

  • javascript 内存泄露

    js内存溢出 JS程序的内存溢出后,表现为程序突然卡死或假死或报错 内存生命周期 分配你所需要的内存(变量、函数、...

  • Javascript内存泄露

    常见的js内存泄露 1. 意外的全局变量 JavaScript 处理未定义变量的方式比较宽松:未定义的变量会在全局...

  • 内存泄露详解

    参考文章: http://mp.weixin.qq.com/s/OXklvbrV2eifK6nCU41gpA ht...

网友评论

      本文标题:javascript内存泄露及解决方案详解

      本文链接:https://www.haomeiwen.com/subject/mpfpfxtx.html