作者:abhbhatt@in.ibm.com?subject=JavaScript%20%E4%B8%AD%E7%9A%84%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2%E6%A8%A1%E5%BC%8F), 系统软件工程师, IBM India
kisundar@in.ibm.com?subject=JavaScript%20%E4%B8%AD%E7%9A%84%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2%E6%A8%A1%E5%BC%8F), 系统软件工程师, IBM India
2007 年 5 月 28 日
如果您知道内存泄漏的起因,那么在 JavaScript 中进行相应的防范就应该相当容易。在这篇文章中,作者 Kiran Sundar 和 Abhijeet Bhattacharya 将带您亲历 JavaScript 中的循环引用的全部基本知识,向您介绍为何它们会在某些浏览器中产生问题,尤其是在结合了闭包的情况下。在了解了您应该引起注意的常见内存泄漏模式之后,您还将学到应对这些泄漏的诸多方法。
JavaScript 是用来向 Web 页面添加动态内容的一种功能强大的脚本语言。它尤其特别有助于一些日常任务,比如验证密码和创建动态菜单组件。JavaScript 易学易用,但却很容易在某些浏览器中引起内存的泄漏。在这个介绍性的文章中,我们解释了 JavaScript 中的泄漏由何引起,展示了常见的内存泄漏模式,并介绍了如何应对它们。
注意本文假设您已经非常熟悉使用 JavaScript 和 DOM 元素来开发 Web 应用程序。本文尤其适合使用 JavaScript 进行 Web 应用程序开发的开发人员,也可供有兴趣创建 Web 应用程序的客户提供浏览器支持以及负责浏览器故障排除的人员参考。
[url=http://www.ibm.com/developerworks/cn/web/wa-memleak/index.html#listing5]
由事件处理引起的内存泄漏模式[/url] 为例来展示三种应对已知内存泄漏的方式。
一种应对 [url=http://www.ibm.com/developerworks/cn/web/wa-memleak/index.html#listing5]
清单 5[/url] 中的内存泄漏的解决方案是让此 JavaScript 对象 [code]obj[/code] 为空,这会显式地打破此循环引用,如清单 6 所示。
[b]清单 6. 打破循环引用[/b]
<html>
<body>
<script type="text/javascript">
document.write("Avoiding memory leak via closure by breaking the circular
reference");
window.onload=function outerFunction(){
var obj = document.getElementById("element");
obj.onclick=function innerFunction()
{
alert("Hi! I have avoided the leak");
// Some logic here
};
obj.bigString=new Array(1000).join(new Array(2000).join("XXXXX"));
[b]obj = null[/b]; //This breaks the circular reference
};
</script>
<button id="element">"Click Here"</button>
</body>
</html> |
清单 7 是通过添加另一个闭包来避免 JavaScript 对象和 DOM 对象间的循环引用。
[b]清单 7. 添加另一个闭包[/b]
<html>
<body>
<script type="text/javascript">
document.write("Avoiding a memory leak by adding another closure");
window.onload=function outerFunction(){
var anotherObj = function innerFunction()
{
// Some logic here
alert("Hi! I have avoided the leak");
};
(function anotherInnerFunction(){
var obj = document.getElementById("element");
obj.onclick=anotherObj })();
};
</script>
<button id="element">"Click Here"</button>
</body>
</html> |
清单 8 则通过添加另一个函数来避免闭包本身,进而阻止了泄漏。
[b]清单 8. 避免闭包自身[/b]
<html>
<head>
<script type="text/javascript">
document.write("Avoid leaks by avoiding closures!");
window.onload=function()
{
var obj = document.getElementById("element");
obj.onclick = doesNotLeak;
}
[b]function doesNotLeak()[/b]
{
//Your Logic here
alert("Hi! I have avoided the leak");
}
</script>
</head>
<body>
<button id="element">"Click Here"</button>
</body>
</html> |
[b]结束语[/b]
本文解释了循环引用是如何导致 JavaScript 中的内存泄漏的 —— 尤其是在结合了闭包的情况下。您还了解了涉及到循环引用的一些常见内存泄漏模式以及应对这些泄漏模式的几种简单方式。
[b]作者简介[/b]
| [img]http://www.ibm.com/i/c.gif[/img]
|
|
[img]http://www.ibm.com/developerworks/i/p-abhattacharya.jpg[/img]
|
[img]http://www.ibm.com/i/c.gif[/img]
|
Abhijeet Bhattacharya 是 IBM 印度软件实验室的一名系统工程师。在过去三年中,他一直是 OS/2 IBM Web Browser 支持团队中的一员。他也具有系统管理领域的相关经验,并参与过 IBM Pegasus 开源创新项目。他目前工作的重点包括分布式计算和 SARPC。他拥有 Rajiv Gandhi Technical University 的工程学士学位。
|
| [img]http://www.ibm.com/i/c.gif[/img]
|
|
[img]http://www.ibm.com/developerworks/i/p-ksundar.jpg[/img]
|
[img]http://www.ibm.com/i/c.gif[/img]
|
Kiran Shivarama Sundar 是 IBM 印度软件实验室的一名系统工程师。在过去三年中,他一直是 OS/2 IBM Web Browser 支持团队中的一员。他同时也具有诸多其他项目的工作经验,包括为 Apache Tuscany Open Source Project 开发命令行工具以及为 IBM 的 EPCIS 团队开发 RFIDIC Installer。目前,Kiran 加入了 IBM WebSphere Adapters 支持团队,负责提供对 JMS 和 MQ 适配器的支持。他已成功获得了 Sun Certified Java Programmer、Sun Certified Web Component Developer 和 Sun Certified Business Component Developer 的认证。他目前所关注的领域包括 Java、J2EE、Web 服务和 SOA。他拥有 Visweshwaraya Technology University 的工程学士学位。
|