jQuery.data会导致内存泄漏吗?

11

以下代码会创建内存泄漏吗?

根据jQuery文档,使用data函数可以避免内存泄漏。确认以下代码是否安全是有用的。

var MyClass = function(el) {
    // Store reference of element in object.
    this.element = $(el);
};

// Store reference of object in element.
$('#something').data('obj', new MyClass('#something'));

为什么你不在全局JS对象中保存引用? - ant_Ti
@ant_Ti 我想要双向访问。例如,在事件处理程序中,我想访问 obj,但我也想能够从 obj 访问元素。 - Lea Hayes
我编辑了问题,删除了循环引用的提及,因为这个例子并不包含循环引用。(尽管它看起来可能有) - mikerobi
4个回答

7
显然,只要DOM元素仍连接到DOM,现有代码将占用额外的内存。但我猜想你是在问,当DOM元素不再使用时,它是否会继续使用额外的内存。
更新:感谢Joey的答案(他已经删除了),我花了一些时间阅读javascript中的内存泄漏,看起来我下面段落中的假设是错误的。由于DOM元素不使用纯粹的垃圾回收,像这样的循环引用通常会防止DOM元素和javascript对象被释放。然而,我相信本答案的其余部分仍然是正确的。
没有深入了解JavaScript引擎如何实现垃圾回收,我不能权威地谈论这个话题。然而,我对垃圾回收的一般理解使我认为,在从DOM中删除#something元素之后,MyClass对象仅引用一个没有其他连接的对象,所以你的代码在这个意义上是“安全”的。垃圾回收的图形算法应该能够识别DOM元素及其MyClass对象是“漂浮在空间中”的,与其他所有东西都没有连接。
此外,jQuery会特意去除与给定DOM元素相关联的数据和事件,一旦它从DOM中被删除。来自documentation的引用:

jQuery确保在通过jQuery方法删除DOM元素以及用户离开页面时删除数据。

因此,假设您始终使用jQuery,一旦对象从DOM中删除,您只会有单向引用,这使得垃圾回收器知道可以清除这些对象。
只要在DOM元素被移除之后没有其他东西引用MyClass对象,就不会出现内存泄漏问题。

0

我想这取决于JavaScript引擎。

你已经准确地提出了问题以进行测试。我在对象中添加了一个长字符串,并在大循环中运行了潜在的泄漏。

结果,我认为IE8和Chrome都没有泄漏。

但我也无法再现这些泄漏模式


0

这可能导致内存泄漏。 jQuery.data方法的理论是使用一个Data内部类来缓存dom元素的数据。

当然,当您删除缓存数据时,jQuery会取消引用该数据。 但是内部缓存是一个不断增长的数组,当您使用它时,它会增加。

因此,在最后,将有非常大的缓存数组,这将导致内存泄漏。 在长期运行的Web应用程序中,这可能会导致内存崩溃。


-4

数据属性只存储字符串值。


2
在jQuery中,它可以是任何JavaScript类型,包括数组或对象。 - ant_Ti
@ant_Ti -- 在文档中哪里写了这个? - Naftali
.data() 的描述中提到了 value,它是新的数据值;它可以是任何 JavaScript 类型,包括数组或对象。 - ant_Ti
@Neal请看以“jQuery.data()方法允许我们附加…”开头的段落(http://api.jquery.com/jQuery.data/)。我的担忧是元素引用存储在对象本身中。 - Lea Hayes
@Lea Hayes,你误解了文档。数据引用并不存储在对象中,而是全局存储,并与DOM节点关联。请查看我的更新答案。 - mikerobi
@Neal,文档从未说过它必须是一个字符串。看一下带有函数原型的大灰色框:http://api.jquery.com/jQuery.data/ - mikerobi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接