JavaScript:我应该担心2011年的内存泄漏吗?

Ran*_*lue 23 javascript memory-leaks

JavaScript中的内存泄漏主题并不经常出现.但是,我偶然发现了这篇写于2007年的文章.作者说:

Internet Explorer和Mozilla Firefox是最常与JavaScript中的内存泄漏相关联的两种Web浏览器.

我还应该担心2011年的JavaScript内存泄漏吗?如果是这样,我应该注意什么?

Mic*_*yan 13

是的,内存泄漏肯定是JavaScript中的一个问题,因为循环引用确实是可能的.内存泄漏的一个非常常见的来源是使用闭包.例如,考虑:

var outerFunction = function(param1, param2, param3) {
     var innerFunction = function() {};
     return innerFunction;
};
Run Code Online (Sandbox Code Playgroud)

上述内容可能会泄漏参数,因为它innerFunction保留了对其构造范围的引用,其中包括该框架的参数.

虽然在许多台式计算机上很容易忽视这些类型的东西,但是RAM很多,这实际上是在内存有限的设备(例如移动电话或机顶盒)上非常明显的事情.作为一个轶事的例子,一些未被命名的网站曾经经常从我的电视访问时崩溃,我的电视内存非常有限.

请注意,这些问题与Web开发人员编写的JavaScript代码有关.尽管可能,底层JavaScript解释器中的内存泄漏问题远远不是问题,并且不是Web开发人员可以合理关注的内容,因为这是浏览器编写者的工作.


jfr*_*d00 13

一个好的javascript开发人员会意识到可能导致内存泄漏的各种设计模式,并且你会避免在你编写的几乎所有页面中编写任何可能导致泄漏的代码.

例如,保持对javascript变量中任何DOM对象的引用将使该DOM对象在内存中保持活动状态,即使它已经从DOM中移除很久并且您打算将其释放.

实际上,泄漏只在某些情况下很重要.这是我特别担心的地方:

  1. 我在计时器上重复做的任何事情,特别是如果它可以长时间运行.例如,如果您有一个可能永远循环的幻灯片,您必须确保幻灯片中的任何内容都不是JS或DOM对象的累积泄漏.
  2. 一个像应用程序一样工作的网页,用户可能会长时间停留在同一页面上,与页面交互,执行ajax调用等等...例如,一个Web邮件应用程序可能是打开的并且在同一个实际的浏览器上文档很长一段时间进行大量的用户和服务器交互.
  3. 一个定期创建和销毁大量DOM元素的网页,例如经常使用ajax来获取大量新HTML的东西.

我真的不担心泄漏的地方:

  1. 一个网页,没有用户可以执行的长时间交互集.
  2. 在加载某个其他页面或重新加载此页面之前很长时间没有停留在屏幕上的网页.

我一直关注的一些关键事项.

  1. 在创建/销毁DOM元素时包含对DOM元素的引用的任何持久JS变量或属性.
  2. DOM对象的任何属性,包含对其他DOM对象的引用或对包含对其他DOM对象的引用的JS对象的引用(这可以在JS/DOM之间创建循环引用和交叉引用,而某些旧版本的浏览器无法解除这些引用).
  3. 我加载临时使用的任何大型数据结构.我确保不会保留对这些大型数据结构的引用.
  4. 任何数据缓存.确保没有任何真正大的内容被缓存,您不希望缓存.确保所有重复使用的缓存不会永远累积并具有某种老化机制来摆脱旧对象.


rob*_*cat 7

没有.

更完整的答案:也许吧.你如此模糊地问这个事实是一个强烈的信号,你个人不太可能需要担心.

在实践中,绝大多数JavaScript代码根本不担心它,并且不需要担心它,因为只有在特定情况下,页面中的内存泄漏最终会影响用户.浏览器和框架很好地覆盖了你的屁股.

您只需回答几个问题:

问:您是否支持使用JavaScript的丰富单页面应用程序?

如果没有,那么不要浪费你的时间担心.如果您(或您的QA或您的客户)发现页面存在内存过量使用问题,请在出现问题时进行修复.

问:你需要支持移动设备吗?你有大量的javascript使用?

移动设备的内存有限,需要额外注意.

如果您正在开发JavaScript繁重的应用程序,并且需要担心内存使用情况,那么...

对于导致JavaScript对象和DOM对象永远不会被垃圾回收的对象的"脏"引用问题对于某些类型的JavaScript应用程序很重要.永远增长的缓存,意外的全局引用以及闭包内的意外引用可能是个问题.

Chrome的Web Inspector中的堆快照工具可以提供帮助.

这是一个git项目,它有一个有用的文档并可以遍历javascript对象:https://github.com/tlrobinson/leakhelper

还有其他工具可以帮助你,但我随着时间的推移编写了自己的工具:1.我们的框架标记了已删除的小部件,因此我编写了代码来从窗口或文档中查找所有数组和对象,以查找被选对象的路径(javascript代码可以'走路关闭,但它肯定有助于找到一些泄漏).2.我使用的另一个技巧是当widget x被删除时,我执行x.leakhelper = window.createElement('leakhelper')和setAttribute小部件的oid,但不将元素添加到文档中.如果DOM元素没有被垃圾收集,那么小部件必须在某处有一个悬空引用.在IE中使用window.collectGarbage()来强制GC,并使用sIEve来检测泄漏的DOM元素(我发现sIEve非常有用).

过时的问题:您是否需要强烈支持IE6或IE7并且您大量使用JavaScript?您以前阅读的大多数可怕泄漏仅发生在<IE8中.如果您支持IE6或IE7,那么您需要好运和坚持(所有框架都会泄漏,并且很难编写甚至没有完美框架的代码 - 我最终编写了我自己的IE防漏代码用于我们的生产用途对于IE6/7用户).即使关闭页面,IE6/IE7泄漏也会持续 - 这就是为什么它们如此令人讨厌.