JScript的内存泄漏

Stella981
• 阅读 697

当一个系统没有妥善地管理它的内存分配时,就被称为内存泄漏,内存泄漏是一个bug,这问题会导致性能下降和运行错误。

微软的Internet Explorer有许多的泄漏问题,最严重莫过于与JScript的交互作用了。当一个Dom对象包含一个对JavaScript对象的引用时(比如一个事件句柄函数event handling function), 并且那个JavaScript对象包含了对那个Dom对象的引用,那么一个环状结构形成了。这本质并不是一个问题。在这时如果没有其他的引用DOM对象和事件句柄时,那么垃圾回收器(一个自动的内存资源管理器)将收回他们的内存,允许它们的空间被再次的分配。垃圾回收可以理解那个环状结构,并不会对它们感到困惑。不幸地是,IE的DOM结构不受JScript管理,它有它自己的内存管理器,它的内存管理器不理解那个环状结构,这导致它变的很困惑,这导致了当环状结构发生的时候,内存回收不再出现。内存不再被回收被称作泄漏,随着时间过去,这会导致内存最终穷尽。内存空间已被用满,导致浏览器死掉。

我们可以对上述进行论证。在第一个程序里,队列测试1,我们将增加10000个DOM对象(span对象),与此同时,删除最近的10个对象。当你运行它,你会发现在windows任务管理器的性能页观察PF(页面文件)使用情况为平稳的正常。PF的改变使用率可以指示内存分配效率.

接下来,运行第二个程序,队列测试2,它的结果不再与测试1相同了,唯一的变动是它对每个对象增加了一个click handler,在Mozilla和Opera中,PF使用保持平稳,但在IE中我们看到PF稳步地增加,内存泄漏导致了每秒数兆字节的增加。通常这个泄漏是不值得注意的。但是Ajax技术变得流行,单页停留时间变的很长, 页面更多的变化,导致失败变得普遍。

IE不能做好它的工作去回收环状结构,这任务落到了我们的身上,如果我们明确地打碎环状机构,那么IE就能回收内存了。根据微软所说,闭包 (closures )会引起内错泄漏,这当然是严重错误的,但是这导致微软给了程序员们一个不好的建议去应对微软的bug。这关闭了从DOM方很容易解决问题的那一面,而交给了事实上不能解决问题的JScript方面。

当我们不再使用一个对象时,我们必须清除它所有的event handlers来破坏循环引用,所有我们必须要做的就是将每个event handler属性设置为null值,这可以明确的进行,又或者我们可以写一个通用的净化函数。

净化程序将一个引用DOM对 象作为参数,它循环元素所有属性,如果发现任何函数,就将其设为null。这将破坏循环引用,允许内存再生。这也将元素的派生元素,这将很好清除循环引 用。净化函数对Mozilla和Opera是无害的,它应用于IE。净化程序应该在移除任何元素时被调用,在removeChild方法,和设置 innerHTML属性的之前使用。

function purge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            n = a[i].name;
            if (typeof d[n] === "function") {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            purge(d.childNodes[i]);
        }
    }
}

最后我们运行第三个程序,队列测试3,净化程序在删除DOM元素之前被调用。

说明:内存泄漏的问题直到IE9才得到解决,所以我们在编程时要格外小心。

作者:Douglas Crockford
原文:JScript Memory Leaks
翻译:blogspot

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
爱库里 爱库里
3年前
图文并茂讲清楚 JavaScript 内存管理
作为一个JavaScript的开发者,大多数情况下你可能不会担心内存管理问题,因为JavaScript引擎会帮你处理这些。但是在开发过程中,你或多或少的会遇到一些相关的问题,比如内存泄漏等,只有了解了内存分配的工作机制,你才会知道如何去解决这些问题。在这篇文章中,我将会向你介绍内存分配和垃圾收集的机制,以及如何避免一些常见的内存泄漏的
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
深入了解 JavaScript 内存泄漏
在任何语言开发的过程中,对于内存的管理都非常重要,JavaScript也不例外。但是如果我们对内存泄漏没有什么概念,就有可能因为内存泄漏,导致许多问题。了解内存泄漏,如何避免内存泄漏,都是不可缺少的。
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Easter79 Easter79
3年前
ThreadLocal 内存泄露的实例分析
前言之前写了一篇深入分析ThreadLocal内存泄漏问题(https://my.oschina.net/thinwonton/blog/1505136)是从理论上分析ThreadLocal的内存泄漏问题,这一篇文章我们来分析一下实际的内存泄漏案例。分析问题的过程比结果更重要,理论结合实际才能彻底分析出内存泄漏的原因。案例与分析
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Wesley13 Wesley13
3年前
Java内存泄漏解析!
前言:内存管理是Java最重要的优势之一,你只需创建对象,Java垃圾收集器会自动负责分配和释放内存。但是,情况并不那么简单,因为在Java应用程序中经常发生内存泄漏。本章会说明什么是内存泄漏,为什么发生,以及如何防止它们。什么是内存泄漏?内存泄漏的定义:应用程序不再使用的对象,垃圾收集器却无法删除它们,因为它们正在被引用。为了理
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这