【问题标题】:Does this code have a memory leak? If so, how do i remove it?这段代码有内存泄漏吗?如果是这样,我该如何删除它?
【发布时间】:2011-07-24 10:58:50
【问题描述】:

我收到了我的前辈从事的一个项目,这个项目的开发牢记整个页面永远不应该重新加载。所以很明显一切都进入了ajax。它有 100 行类似这样的行。

 function iCreateProblems()
    {
        //some rubbish
        document.getElementById('some_rubbish').innerHTML=obj1.responseText;
    }

典型的响应文本是"<div onClick="handleMe()">some thing stupid</div>"; 页面上有三个主要的 div,所有内容都重复加载并重新加载到这些 div 中。现在据我了解,这显然会导致内存泄漏,对吗?那么我该如何解决这个问题?大约有 8000 行代码以这种方式运行。有没有办法修复内存泄漏?有数百个像这样分配的处理程序。我现在该怎么办?

【问题讨论】:

  • 是什么让你认为会有内存泄漏? JavaScript 在浏览器内部进行解析并完全由它管理,很难相信 DOM 操作会导致任何泄漏,无论它看起来多么复杂。您是否正在寻找代码优化?
  • 你能解释一下代码试图提供的功能吗?如果可能,您可能希望完全替换它。
  • 另外,您可能对此感兴趣:javascript.crockford.com/memory/leak.html

标签: javascript ajax memory-leaks


【解决方案1】:

不,不应该。你不直接在 js 中处理内存;垃圾收集器会删除所有不需要的内容,如果您覆盖内容,则无需显式删除 div 的内容。

【讨论】:

  • 但是所有响应文本都有事件处理程序。那些事件处理程序呢?据我了解,一旦数据被覆盖,这些事件处理程序就不会从内存中删除。不是这样吗?
  • @sasidhar:好吧,您可以删除事件处理程序(请参阅stackoverflow.com/questions/803936/…),但我怀疑它会提高页面效率
  • 如果你写<div onclick="func();">something</div>一万次你就没有内存泄漏。如果您修改每个 div 的“内部”html,您将获得(新内容),没有内存泄漏,并且处理程序保持不变(您正在更改 div 的内容);如果您在更新内容时需要删除事件处理程序,那么您必须故意这样做,它不是“自动的”。无论如何,非内存泄漏,只是一个等待事件发生的处理程序
【解决方案2】:

没有看到其余的代码,就无法判断。尽管人们在这里说什么,但很容易在 JS 中创建内存泄漏而没有注意到它。 JS 垃圾收集器通常的工作方式是标记“可访问”的变量。当变量的“标记”被取消并且没有重新应用时,变量被认为是“不可访问的”(也就是说,程序员的任何函数或范围都完全无法访问它们)。标记被删除后,它们最终会被垃圾收集器清理掉。

一个人为的内存泄漏示例是:

(function() {
  var xhr = $.get('http://google.com/');
  $('a').click(function() {
    console.log('hello');
  });
})();

只要页面上存在该元素,并且该事件侦听器绑定到它,变量xhr永远被垃圾收集器清理。即使xhr 从未在您的代码中的任何地方使用过,垃圾收集器也会拒绝清理它,因为您的事件侦听器仍然可以“访问”它。

edit:我还应该提一下,写得不好的 JS 引擎中的错误也可能导致内存泄漏。 (另请参阅:Internet Explorer)。大多数 DOM 库都考虑到了这一点,并确保避免这些问题,但它仍然可能发生。对于这些内存泄漏,您需要为该特定引擎找到解决方法。

【讨论】:

  • 你的例子是纯 JavaScript 吗?
  • 是的,我的例子是纯 javascript。我的代码覆盖了我提到的三个主要 div 中的 innerHTML。那么这是否意味着被覆盖元素的事件处理程序仍然存在于内存中?
  • 您的示例不是内存泄漏。泄漏是程序无法将分配的内存释放回操作系统的情况,尽管一旦从 DOM 中删除匹配的<a> 标记,一切都可以释放。您的场景称为内存使用情况。我同意,可能会无意中延长和不必要的使用,但不会泄露。此外,有些引擎优化了该场景并且不在词法范围内保存对未使用变量的引用。事实上,我认为大多数现代引擎都允许xhr 立即发布。
  • davin,你是对的,从技术上讲,这不是内存泄漏。这是一个可以创造一个机制的例子。如果我将$('a').click() 更改为setInterval() 留下无法访问该ID,你会高兴吗?此外,事实上,您不能依赖 JS 引擎来优化浏览器环境中的任何内容。你必须假设最坏的情况。
  • -1 因为开始了一般性讨论而不是回答问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多