jQuery(JavaScript)和gc如何工作?
callBack是一个作为JSON响应回调运行的函数。
执行callBack函数时内存会是什么?
我想听到的是数据对象和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;
}
});
}
答案 0 :(得分:1)
通过JavaScript引用传递对象,因此访问autoCompleteData
所访问的对象与autocomplete
插件使用的对象相同。
因此,变量autoCompleteData
不会被垃圾收集(但这对您的程序没有害处,因为它是自动完成插件所需的。
然而,data
对象应该被垃圾收集,因为没有提供对它的引用,并且它已经超出了范围。
此外,重要的是要注意垃圾收集对jQuery的作用不同;它的行为与JavaScript(以及ofc,所有其他JavaScript框架)的行为相同。
答案 1 :(得分:1)
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引擎没有要求保留该数据,直到调用select回调为止以前。数据是否实际上是垃圾收集,取决于.autocomplete()的内部实现是否将其存储在某个地方,直到调用select
方法为止。
仅供参考,垃圾收集的确切时间对于大数据(数兆字节),数以万计的数据(大量数据加起来数百兆字节)最为重要。如果测量的是大小的数据以千字节甚至几百千字节为单位只有一个,那么内存是否立即被垃圾收集或回调被调用的确切时间并不是那么重要,因为浏览器现在可以访问合理的内存量如果你正在处理巨大的数据或处理数以万计的数据或重复做某些事情并且有某种泄漏,那些都可能导致问题(特别是在移动设备上),但是像你这样的例子不太可能导致问题,除非数据集相对于浏览器中可用的内存大。