垃圾回收和jQuery?

3

jQuery (JavaScript) 和 gc 是如何工作的?

callBack 是一个函数,作为 JSON 响应的回调运行。

当 callBack 函数执行时,内存中会有什么内容?

我想要听到的是,data 对象和 autoCompleteData 将被垃圾回收。仅存储在 $("input#reciever") 中的数据会留存在内存中。

这是正确的吗?

//The code in question:

var callBack = function(data) {
    var autoCompleteData = jQuery.map(data.receivers, function(receiver, i){
          return {label: receiver.name, id: receiver.id };
    });

    $("input#reciever").autocomplete({
        source: autoCompleteData,
        select: function(event, receiver) {
            $("input#reciever").val(receiver.item.label); 
            $("input#recieverId").val(receiver.item.id);
            return false;
        }

    });
}

相关问题:https://dev59.com/Z3RA5IYBdhLWcg3wsgBP - Blazemonger
2个回答

1

在JavaScript中,对象是通过引用传递的,因此访问autoCompleteData所达到的对象将是autocomplete插件使用的相同对象。

由于这个原因,变量autoCompleteData不会被垃圾回收(但这对您的程序没有任何损害,因为它是自动完成插件所必需的)。

然而,data对象应该被垃圾回收,因为没有任何东西提供对它的引用,并且它已经超出了作用域。

此外,需要注意的是,垃圾回收在jQuery中的工作方式与JavaScript相同(当然,也适用于所有其他JavaScript框架)。


如果我理解正确,自动完成插件不会循环遍历我的autoCompleteData并设置内部参数,而是每次按键时直接循环遍历autoCompleteData对象。如果是这样的话,我同意只有数据对象应该被垃圾回收。感谢您对插件工作原理的解释。 - user425367

0
在Javascript中,垃圾回收通过释放任何其他javascript代码没有引用的对象的内存来工作。如果没有人引用它,它就不能再被使用了,因此可以安全地释放。
对一个对象的引用可以来自变量或仍然活动的执行范围。
在上面的例子中,在等待.autocomplete()函数完成时,你的代码中的所有内容仍然在作用域内,不会进行垃圾回收。这意味着autoCompleteData将被保留(而不是垃圾回收),直到.autocomplete()方法完全执行完毕。这是正常的、预期的,并且实际上在许多地方都是必需的。
作为一个原因的衡量,为什么这些数据仍然在作用域内,变量autoCompleteData仍然在select回调函数的作用域内。在select回调函数中引用该变量是合法和正确的。因此,JS引擎必须在它不再在作用域内并且不能被任何代码引用之前不进行垃圾回收。
在某些情况下,您可以通过显式清除变量来使内存可供垃圾回收。
例如,如果您像这样重构代码:
var callBack = function(data) {
    $("input#reciever").autocomplete({
        source: jQuery.map(data.receivers, function(receiver, i){
          return {label: receiver.name, id: receiver.id };,
        select: function(event, receiver) {
            $("input#reciever").val(receiver.item.label); 
            $("input#recieverId").val(receiver.item.id);
            return false;
        }

    });
}

然后,自动完成数据仅存在于.autocomplete()的参数中,并且可能更早地有资格进行垃圾回收,因为JS引擎没有要求在调用选择回调之前保留该数据。实际上是否立即进行垃圾回收取决于.autocomplete()的内部实现是否将其存储在持续到调用select方法的某个位置。

顺便说一下,垃圾回收的确切时间最关键的是大块数据(许多兆字节),大量数据(许多数据片段总共达到数百兆字节)。如果某些东西的大小以千字节甚至几百千字节为单位,并且只有一个,那么内存是否立即进行垃圾回收或在回调被调用时进行垃圾回收的确切时间并不是非常重要,因为现代浏览器可以访问合理数量的内存。如果您正在处理巨大的数据块或处理大量数据块或重复执行某些操作并且存在某种泄漏,则所有这些都可能会导致问题(特别是在移动设备上),但是像上面的示例一样的示例不太可能会引起问题,除非数据集相对于浏览器中可用的内存很大。


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