【问题标题】:When is this scope/closure being garbage collected in javaScript?这个作用域/闭包何时在 JavaScript 中被垃圾收集?
【发布时间】:2016-05-22 17:52:09
【问题描述】:

我正在做一门课程,它正在经历范围/闭包并简要提到垃圾收集。在课程中提出一个问题:

示波器能停留多长时间?答案是——直到 不再有任何引用它。是的,所以我们基本上说的是 过去,闭包有点像对隐藏作用域对象的引用。 所以只要有一些函数仍然有一个闭包 范围,该范围将保持不变。但一旦关闭 消失,范围可以收集垃圾。 "

var sum = function sumHndlr(x, y) {
    if (y !== undefined) {
        return x + y;
    } else {
        return function(y) {
            return x + y;
        }
    }
}

所以对我来说,对闭包的引用是当我们将函数分配给sum 变量时,但这并不意味着它会永远持续下去,或者我不理解 js 在编译器方面的执行方式解析器等?

【问题讨论】:

  • “永远”是什么意思?是的,关闭将持续到sum,但这不是永远...
  • 好吧,也许我需要更清楚地了解垃圾收集的实际情况。因为目前我正在考虑垃圾收集,例如当您删除事件侦听器时。也许你可以解释为什么它不是永远的。谢谢!
  • sum/sumHndlr 没有关闭。你必须调用它(没有y)才能得到一个。然后,只要你把它放在某个地方,它就会一直存在(连同它关闭的x)。如果您希望我们提供更多信息,请向我们展示该电话。
  • 对——我认为这是对的。内部函数是记住它的词法范围的函数。我想我不明白那怎么会消失?对我来说,我认为如果您将sum 分配给null 或其他东西,就会发生这种情况。但现在我猜了。
  • @AntonioOrtiz:从函数到作用域的引用永远不会消失。只有当所有指向它的函数都被回收时,该范围才能被垃圾回收。如果您执行了var add2 = sum(2);,那么分配add2 = null 将使函数符合垃圾回收条件。

标签: javascript garbage-collection closures


【解决方案1】:

非常简单地说,垃圾收集是 Javascript 解释器/虚拟机的后台进程,它会自动释放程序不再需要的对象的内存。

例如,由于您将其视为事件侦听器:当您从某个事件调度程序中删除事件侦听器(通常是一个函数)时,程序的其他部分很可能不会引用该事件侦听器。因此,垃圾收集器可以并且将(在某个未知时间)释放事件侦听器占用的内存。

由于闭包引用了一个作用域对象,为了对闭包进行垃圾回收,它不仅需要未被引用,还需要作用域。

如果我修改一下你的例子:

/* some stuff ... */
function add10(a) {
  var adder = function (x) {
     return function(y) {
       return x + y;
     }
  }

  var sum = adder(10); //creates a closure
  return sum(a);
}

var thirty = add10(20);

/* Some more stuff ... */

在调用add10 之后,即使程序继续执行一些东西,垃圾收集器也可以释放与闭包sum 关联的内存,因为它不再被引用,也没有 是与之关联的范围。

而在本例中:

/* some stuff ... */
function add10AndGet20Adder(a) {
  var adders = function (x, y) {
     return [function(z) {
       return x + z;
     }, function(z) {
       return y + z;
     }]
  }

  var sums = adders(10, 20); //creates a closure
  return [sums[0](a), sums[1]];
}

var result = add10AndGet20Adder(50);
var sixty = result[0];
var add20 = result[1];

/* Some more stuff ... */

当执行更多的东西时,sums[0] 不再被引用,BUT add20 (sums[1]) 仍然有引用xy 的作用域,因此sums 中的两个闭包都不能被垃圾收集器释放,直到add20 被程序引用。

我希望这能让它更清楚,尽管这些示例当然与真实代码相去甚远。在实践中,只有在开发具有复杂闭包使用的长期程序(例如单页应用程序或 nodeJS 服务器)时才需要担心这一点。否则,闭包的内存使用不太可能成为问题。

这个 SO 问题提供了有关 Javascript 垃圾收集的更多详细信息:What is JavaScript garbage collection?

【讨论】:

  • 感谢您使用函数的独特形式(第二个)进行的详细解释-也许对我来说是独一无二的,因为我从未见过它;)我还将检查 JS 垃圾还有收藏链接!干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
相关资源
最近更新 更多