使用延迟时是否存在潜在的内存泄漏?

时间:2016-11-29 19:47:36

标签: javascript jquery jquery-deferred

我在代码中的某个地方得到jQuery.Deferred,并且我向它添加了几个回调,这些回调是短期对象的成员方法。我想知道在这种情况下是否存在任何类型的内存泄漏漏洞,类似于.NET事件处理程序。

我正在检查jQuery的代码,但没有看到任何清除回调的部分。我甚至没有找到延迟对象的生命周期应该在哪里结束。

有人可以就这个话题说清楚吗?

修改

正如我在想的那样,它缩小到这个问题。在JavaScript中,将持有对象(而不是原型)的成员函数的引用否认该对象不是GC-d?因为jQuery似乎在延迟对象的回调中持有这些函数引用。

3 个答案:

答案 0 :(得分:1)

我会回答我的问题,因为在经过一番思考之后,它似乎很简单。实际上,JavaScript函数并不属于与它们定义的对象“紧密”,除非它们例如用{{1}}手动绑定,但这是另一种情况。

因此,如果函数是自己的生命,那么持有对它们的引用不应该拒绝收集最初定义它的对象。

此外,我必须注意,如果我没有对延迟对象本身进行直接或关闭的引用,这一切都无关紧要,因为每当它完成作业(已解决/拒绝)时,它都将是可收集的。

如果有任何假设错误,请更有经验的人纠正我。

答案 1 :(得分:1)

  

我还没有看到任何清除回调的部分。

当承诺结算(履行或拒绝)时,回复将被清除。

  

我甚至没有找到延迟对象的生命周期应该结束的地方。

当没有任何东西可以引用它时,承诺的生命周期就会结束。

通常有两件事可以引用它:解析器(例如,超时,ajax请求等)最终会解决这个承诺,以及存储承诺的实体,因为他们想要在以后使用它(即其结果) 。 promise对象依次保存对所有回调(直到结算)和结果值(自结算)的引用。

如果承诺永远不会被解决,附加了回调,并且被某些引用阻止被垃圾收集,则可能发生。这是非常罕见的。

  

在JavaScript中,是否会保持对对象(而不是原型)的成员函数的引用,拒绝该对象成为GC-d?

不,一般不会。 javascript中没有“成员”,只是普通的独立函数。

当然,当作为闭包时,函数可以保存对象的引用,并且不会被收集。

答案 2 :(得分:0)

从我所看到的(以及一些轻松阅读:Do never resolved promises cause memory leak?),未解决的Promises - 或Deferrered s的可忽略不计影响 - - 除非你是:

  • 创建一个大数字:任何对象的数百个实例都是需要特殊处理和设计的拖动
  • 维护对阻止GC运行清除任何超出范围的项目的实例的引用