JavaScript 中的内存泄露模式
From dW
JavaScript 是用来向 Web 页面添加动态内容的一种功能强大的脚本语言。它尤其特别有助于一些日常任务,比如验证密码和创建动态菜单组件。JavaScript 易学易用,但却很容易在某些浏览器中引起内存的泄漏。在这个介绍性的文章中,我们解释了 JavaScript 中的泄漏由何引起,展示了常见的内存泄漏模式,并介绍了如何应对它们。
注意本文假设您已经非常熟悉使用 JavaScript 和 DOM 元素来开发 Web 应用程序。本文尤其适合使用 JavaScript 进行 Web 应用程序开发的开发人员,也可供有兴趣创建 Web 应用程序的客户提供浏览器支持以及负责浏览器故障排除的人员参考。

Internet Explorer 和 Mozilla Firefox 是两个与 JavaScript 中的内存泄漏联系最为紧密的浏览器。两个浏览器中造成这种问题的“罪魁祸首”是用来管理 DOM 对象的组件对象模型。本机 Windows COM 和 Mozilla's XPCOM 都使用引用计数的垃圾收集来进行内存分配和检索。引用计数与用于 JavaScript 的标记-清除式的垃圾收集并不总是能相互兼容。本文侧重介绍的是如何应对 JavaScript 代码中的内存泄漏。有关如何处理 Firefox 和 IE 中 COM 层内存泄漏的更多信息,请参看?参考资料。
在上述清单中,closureDemoInnerFunction
?是在父函数?closureDemoParentFunction
?中定义的内部函数。当用外部的 x?对?closureDemoParentFunction
?进行调用时,外部函数变量?a?就会被赋值为外部的 x。函数会返回指向内部函数?closureDemoInnerFunction
?的指针,该指针包括在变量?x?内。
外部函数?closureDemoParentFunction
?的本地变量?a?即使在外部函数返回时仍会存在。这一点不同于 C/C++ 这样的编程语言,在 C/C++ 中,一旦函数返回,本地变量也将不复存在。在 JavaScript 中,在调用closureDemoParentFunction
?的时候,带有属性?a?的范围对象将会被创建。该属性包括值?paramA,又称为“外部 x”。同样地,当?closureDemoParentFunction
?返回时,它将会返回内部函数?closureDemoInnerFunction
,该函数包括在变量?x?中。
由于内部函数持有到外部函数的变量的引用,所以这个带属性?a?的范围对象将不会被垃圾收集。当对具有参数值?inner x?的?x?进行调用时,即?x("inner x")
,将会弹出警告消息,表明 “outer x innerx”。
清单 4?简要解释了 JavaScript 闭包。闭包功能非常强大,原因是它们使内部函数在外部函数返回时也仍然可以保留对此外部函数的变量的访问。不幸的是,闭包非常易于隐藏 JavaScript 对象 和 DOM 对象间的循环引用。



回页首
?
参考资料
学习- 您可以参阅本文在 developerWorks 全球站点上的?英文原文?。
“JavaScript and the Document Object Model”(Nicholas Chase,developerWorks,2002 年 7 月):为 JavaScript 开发人员介绍了 DOM。
“跨越边界:闭包”(Bruce Tate,developerWorks,2007 年 1 月):有关闭包的入门文章(基于 Ruby,但理论上也可以应用到 JavaScript)。
“JavaScript 中的有限状态机,第 1 部分: 设计一个小部件”(Edward J. Pring,developerWorks,2007 年 1 月):使用闭包和 JavaScript 的其他高级特性的有趣练习。
“A re-introduction to javascript”(Simon Wilson,Mozilla.org):有关 JavaScript 及其特性的深入介绍。
“Using XPCOM in JavaScript without leaking”—avid Baron,Mozilla.org):解释了 Firefox 为何使用引用计数来进行内存分配以及它又是如何进行这种分配的。?
“对 HTML 页上 DOM 对象循环引用导致内存泄漏”(Microsoft 帮助和支持):了解 Microsoft 对 IE 中的内存泄漏作何解释。
“Memory leakage in Internet Explorer -- revisited”(Volkan Ozcelik,The Code Project,2005 年 11 月):有关 JavaScript 中常见的内存泄漏原因(针对 IE)的教程式介绍。
“developerWorks Web 开发专区:内含大量有关 Web 2.0、Ajax、wikis、PHP、mashups 和其他 Web 项目的资源。