jQuery中$ .cache的目的是什么?

时间:2012-02-16 02:40:30

标签: jquery dom memory-leaks

我看到通过.on()注册的事件处理程序保存在$.cache中。 我还看到事件处理程序也保存在$(elem).data()

$.cache中保存的对象是指注册事件的DOM节点。当DOM节点被分离时,这会导致内存泄漏,这会使.off()调用成为必需的。

我有一种情况,我不知道DOM节点(我附加事件处理程序)何时被分离。虽然我可以在我的代码中保存对该DOM节点的引用并调用.off()进行清理,但这似乎不太好,因为知道何时删除DOM节点并不是直截了当的。

最好的方法是什么?

2 个答案:

答案 0 :(得分:16)

  

“这样做的最佳方式是什么?”

如果您要使用jQuery,必须使用其API来删除元素,并且您必须使用正确的方法,否则,如您所述,您将有内存泄漏。< / p>

如果您不知道DOM节点何时被删除,以及它是否导致泄漏,我认为这意味着您正在使用另一个库和jQuery。出于这个原因,这不是一个好主意。

您需要确保jQuery删除受jQuery影响的任何元素。您还没有明确设置$.cache中存储的一些数据。这意味着应该使用jQuery删除所有元素,而不仅仅是那些认为可能包含数据的元素。


  

“jQuery中$.cache的目的是什么?”

将处理程序和其他数据与元素相关联。数据和元素之间的链接基本上是存储在元素上的expando属性上的序列号。

如果删除没有jQuery的元素,$.cache中的关联数据将成为孤立数据。

这种方法的目的是防止潜在的泄漏。不幸的是,它可能会造成更严重的泄漏。

答案 1 :(得分:6)

我遇到了类似的情况,其中Knockout用于添加和删除文档中的dom树。但是,jquery用于将事件侦听器附加到这些dom树。当knockout从文档中删除dom元素时,侦听器不会被解除绑定,因此dom树永远不会有资格进行垃圾回收。我们添加了一个清理函数,每次哈希更改时都会遍历jquery $ .cache,并找到绑定到文档中不存在的dom树的处理程序。然后它取消绑定听众,从而使得dom树有资格进行垃圾收集并修复我们看到的大部分泄漏,即用于泄漏13MB的应用程序往返,现在它在这些更改时仅泄漏3MB。

for (var i in $.cache) {
            if ($.cache.hasOwnProperty(i)) {

                if ($.cache[i].handle && $.cache[i].handle.elem && document !== $.cache[i].handle.elem && !jQuery.contains(document, $.cache[i].handle.elem)) {
                    //we have an event handler pointing to a detached dom element!
                    //this is a memory leak as this detached dom element cannot be garbage collected until
                    //all references to it are removed. So lets delete the event handler to get memory back!
                    var orphan = $($.cache[i].handle.elem);
                    $('body').append(orphan);
                    orphan.off();
                    orphan.remove();
                    orphan = null;
                }
            }
        }