日期:2014-05-16  浏览次数:20413 次

JavaScript 内存泄露

1 原文信息


1.1 标题


JavaScript Memory Leaks

1.2 网址


[http://nesj.net/blog/2012/04/javascript-memory-leaks/]

2 JavaScript 内存泄露



2.1 什么是内存泄露


内存泄露的定义是:系统为应用程序分配了内存,但在这部分内存不会再使用的情况下时,也不能被重新分配。通常情况下,在 DOM 元素以及事件句柄不再被引用或者不可到达时,垃圾收集器会负责收集它们。然而,内存泄露是对于早期的IE浏览器版本(IE7或者更早的)不可避免的,因为这时内存管理器对 javascript 内存的生存周期处理得并不是很好,并且直到内存循环被通过赋值为 null 的方式强制打破后,才会重新声明这片内存。

2.2 为什么内存泄露需要引起你的注意?


内存泄露通常是因为大型的 web 应用程序中的内部编程错误引起的。当被浪费内存增长得超出系统能够提供的最大内存限度时,web 应用程序的性能将会被大大降低。作为一名 web 程序开发者,能够开发一个 web 应用程序来满足功能需求,这仅仅只是第一步而已,性能要求与完成 web 应用程序基本功能同等重要,不然的话,会增加导致潜在的失败可能性及导致浏览器的崩溃。

2.3 在 javascript 中,什么是主要导致内存泄露的主要原因呢?



2.3.1 循环引用


一个简单的例子是一个通过 javascript 对象引用的 DOM 对象,并且在同时正在应用同样一个或者另外一个 javascript 对象,这个 DOM 对象可能会导致内存泄露。尽管脚本已经停止运行,这个DOM元素的引用不将会被垃圾回收器回收。这种模式通常发生在一系列的对象引用并且非常难于检测当前对象是否还存在引用。为了打断循环引用,要么将 javascript 对象指向 DOM 对象,要么将 DOM 对象赋值为 null。

2.3.2 javascript 闭包


因为 javascript 作用域的局限性,很多特性都是依赖 javascript 闭包方式实现的。如果你想了解更多关于闭包的知识,可以查看我之前关于 javascript 作用域和闭包的相关文章。

闭包可以导致内存泄露,因为内部函数保存了一个外部函数变量的引用,所以尽管在这个函数已经返回的情况下,内部函数持续访问定义在外部函数的私有变量。在页面完成加载的情况下,取消所有事件句柄的链接状态,是对 javascript 编程者来说最好的挑战。

2.3.3 DOM 插入顺序


一个临时创建的变量,无论 2 个不同作用域的 DOM 对象被关联在一起时。当这个 DOM 对象改变作用域到 document 时, 这个临时对象的情形就不太好办了。正如那句话所说,DOM 对象应该按照从页面中顶部到页面底端的顺序已经存在的 DOM 元素依次附加创建,这样他们总是能处在 document 作用域中,就不需要创建临时对象了。

2.3.4 怎么检测内存泄露?


对于开发者来说,通常内存泄露非常难于检测。因为内存泄露可能是由在大量代码中的无意识的错误引起的,并且,通常情况下这些小错误不会影响到应用程序的功能,直到系统内存被耗尽时,才会发生。这也是为什么性能测试收集应用程序的性能数据通常都需要持续一个长的测试时间原因。

一个最简单检测内存泄露的方法是,通过任务管理器来监控内存的使用量。运行程序,同时在 chrome 浏览器中打开一个分开的标签页,检测是否随着时间的流逝内存的使用量逐渐增加。也有其他的调试工具可以提供内存检测特性,例如:Chrome 开发者工具。网上有一个 Google 开发者使用 Heap Profiling 特性的教程。

2.3.5 参考资料


1. [http://javascript.crockford.com/memory/leak.html]
2. [http://msdn.microsoft.com/en-us/library/Bb250448]
3. [http://www.ibm.com/developerworks/web/library/wa-memleak/]

3 好词好句


closure 闭包
trapped 使受限制
unintentional 无意识的
starvation 绝食  memory starvation (内存耗尽)
garbage 垃圾 garbage collectors 垃圾回收器

4 译者的想法


依然记得使用 extjs V4.2 定时画曲线图时,内存泄露时的痛苦情景。使得编写的程序没有内存泄露,能让 web 程序更加稳定地运行。

最初翻译文章的想法是,既可以锻炼自己的英语水平,又可以学习到编程技术,一举两得。提升英文水平,那就得总结,比如总结下这篇文中用到的好词好句,总结可以解决的解决办法。