关于Javascript的内存泄漏问题(4)

作者:海啸 来源:海啸博客 时间:2008-04-15 07:46:00 

Cross-Page Leaks

Cross-Page Leaks和下一节提到的Pseudo-Leaks在我看来,就是IE的bug,虽然MS死皮赖脸不承认:)

大家可以看看这段例子代码:

<html> 
<head> 
<script language="JScript"> 
// 这个函数会引发Cross-Page Leaks
function LeakMemory()  
{
    var hostElement=document.getElementById("hostElement");

    // Do it a lot, look at Task Manager for memory response 

    for (i=0 ;i<5000;i++){
        var  parentDiv = document.createElement("<div onClick='foo()'>");
        var  childDiv = document.createElement("<div onClick='foo()'>");

        //  This will leak a temporary object 
        parentDiv.appendChild(childDiv);
        hostElement.appendChild(parentDiv);
        hostElement.removeChild(parentDiv);
        parentDiv.removeChild(childDiv);
        parentDiv = null ;
        childDiv = null ;
     }
     hostElement = null ;
}

// 而这个函数不会引发Cross-Page Leaks
function CleanMemory()   
{
      var hostElement = document.getElementById("hostElement");

      //  Do it a lot, look at Task Manager for memory response 

      for (i=0;i<5000;i++)
      {
         var parentDiv = document.createElement("<div onClick='foo()'>");
         var childDiv = document.createElement("<div onClick='foo()'>");

         //  Changing the order is important, this won't leak 
         hostElement.appendChild(parentDiv);
         parentDiv.appendChild(childDiv);
         hostElement.removeChild(parentDiv);
         parentDiv.removeChild(childDiv);
         parentDiv = null ;
         childDiv = null ;
       }
       hostElement  =   null ;
}
</script> 
</head> 
<body> 
<button onclick="LeakMemory()"> Memory Leaking Insert </button> 
<button onclick="CleanMemory()" > Clean Insert </button> 
<div id="hostElement"></ div > 
</body> 
</html> 

LeakMemory和CleanMemory这两段函数的唯一区别就在于他们的代码的循序,从代码上看,两段代码的逻辑都没有错。

但LeakMemory却会造成泄露。原因是LeakMemory()会先建立起parentDiv和childDiv之间的连接,这时候,为了让 childDiv能够获知parentDiv的信息,因此IE需要先建立一个临时的scope对象。而后parentDiv建立了和 hostElement对象的联系,parentDiv和childDiv直接使用页面document的scope。可惜的是,IE不会释放刚才那个临时的scope对象的内存空间,直到我们跳转页面,这块空间才能被释放。而CleanMemory函数不同,他先把parentDiv和 hostElement建立联系,而后再把childDiv和parentDiv建立联系,这个过程不需要单独建立临时的scope,只要直接使用页面 document的scope就可以了, 所以也就不会造成内存泄露了

详细原因,大家可以看看http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp这篇文章。

IE 6中垃圾回收算法,就是从那些直接"in scope"的对象开始进行mark清除的:

Every variable which is "in scope" is called a "scavenger". A scavenger may refer to a number, an object, a string, whatever. We maintain a list of scavengers – variables are moved on to the scav list when they come into scope and off the scav list when they go out of scope.

Pseudo-Leaks

这个被称为“秀逗泄露”真是恰当啊^-^

看看这个例子:

<html> 
<head> 
<script language="JScript"> 
function LeakMemory()
{
    //  Do it a lot, look at Task Manager for memory response 
    for (i=0;i<5000;i++)
    {
        hostElement.text = "function foo(){}" ; // 看内存会不断增加
    }
}
</script> 
</head> 
<body> 
<button onclick=" LeakMemory()"> Memory Leaking Insert </button> 
<script id="hostElement">function foo(){}</script> 
</body> 
</html> 

MS是这么解释的,这不是内存泄漏。如果您创建了许多无法获得也无法释放的对象,那才是内存泄漏。在这里,您将创建许多元素,Internet Explorer 需要保存它们以正确呈现页面。Internet Explorer 并不知道您以后不会运行操纵您刚刚创建的所有这些对象的脚本。当页面消失时(当您浏览完,离开浏览器时)会释放内存。它不会泄漏。当销毁页面时,会中断循环引用。

唉~~~

详细原因,大家可以看看http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp这篇文章。

其它一些琐碎的注意点:
■ 变量定义一定要用var,否则隐式声明出来的变量都是全局变量,不是局部变量;
■ 全局变量没用时记得要置null;
■ 注意正确使用delete,删除没用的一些函数属性;
■ 注意正确使用try...cache,确保去处无效引用的代码能被正确执行;
■ open出来的窗口即使close了,它的window对象还是存在的,要记得删除引用;
■ frame和iframe的情况和窗口的情况类似。

标签:内存,泄露,javascript
0
投稿

猜你喜欢

  • python生成九宫格图片

    2022-09-09 04:46:34
  • pycharm debug功能实现跳到循环末尾的方法

    2023-08-03 02:29:01
  • python求解水仙花数的方法

    2023-10-08 12:07:28
  • php中重定向网页跳转方法总结案例教程

    2023-06-11 20:47:18
  • Pytorch maxpool的ceil_mode用法

    2023-03-20 13:28:05
  • Python如何实现转换URL详解

    2021-06-28 20:23:46
  • python中json格式数据输出的简单实现方法

    2021-03-04 22:19:19
  • 在thinkphp5.0路径中实现去除index.php的方式

    2024-05-11 09:54:34
  • Python正则简单实例分析

    2023-03-10 16:49:59
  • php笔记之:初探PHPcms模块开发介绍

    2024-05-11 09:54:26
  • JavaScript深入理解作用域链与闭包详情

    2024-04-19 10:04:07
  • python实现移位加密和解密

    2022-03-20 09:09:27
  • 使用Python AIML搭建聊天机器人的方法示例

    2022-01-04 10:14:28
  • 详解Python在使用JSON时需要注意的编码问题

    2022-08-03 22:06:36
  • 连接MySQL时出现1449与1045异常解决办法

    2024-01-16 14:07:02
  • SQL Server跟踪数据实现索引优化向导

    2009-02-13 17:14:00
  • 浅谈Python 的枚举 Enum

    2021-02-01 16:42:15
  • 不同浏览器空格的宽度

    2007-08-22 08:29:00
  • python 基于 tkinter 做个学生版的计算器

    2022-07-30 18:43:54
  • python的sorted函数及使用解析

    2022-03-02 05:52:21
  • asp之家 网络编程 m.aspxhome.com