本文介绍了使用 node.js 进行垃圾收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇嵌套函数的 node.js 模式如何与 v8 的垃圾收集器一起工作.这是一个简单的例子

I was curious about how the node.js pattern of nested functions works with the garbage collector of v8.here's a simple example

readfile("blah", function(str) {
   var val = getvaluefromstr(str);
   function restofprogram(val2) { ... } (val)
})

如果 restofprogram 是长时间运行的,那是不是意味着 str 永远不会被垃圾收集?我的理解是,使用节点,您最终会得到很多嵌套函数.如果在外部声明了 restofprogram,这是否会被垃圾收集,因此 str 不能在范围内?这是推荐的做法吗?

if restofprogram is long-running, doesn't that mean that str will never get garbage collected? My understanding is that with node you end up with nested functions a lot. Does this get garbage collected if restofprogram was declared outside, so str could not be in scope? Is this a recommended practice?

编辑我不打算让问题复杂化.那只是粗心大意,所以我修改了它.

EDIT I didn't intend to make the problem complicated. That was just carelessness, so I've modified it.

推荐答案

简单的答案:如果 str 的值没有从其他任何地方引用(并且 str 本身是未从 restofprogram 引用)一旦 function (str) { ... } 返回,它将变得无法访问.

Simple answer: if value of the str is not referenced from anywhere else (and str itself is not referenced from restofprogram) it will become unreachable as soon as the function (str) { ... } returns.

详细信息:V8 编译器将真正的局部变量与由闭包捕获的所谓的上下文变量区分开来,由with语句或eval 调用.

Details: V8 compiler distinguishes real local variables from so called context variables captured by a closure, shadowed by a with-statement or an eval invocation.

局部变量存在于堆栈中,并在函数执行完成后立即消失.

Local variables live on the stack and disappear as soon as function execution completes.

上下文变量存在于堆分配的上下文结构中.当上下文结构消失时,它们就会消失.这里要注意的重要一点是来自同一范围的上下文变量存在于相同结构中.让我用一个示例代码来说明它:

Context variables live in a heap allocated context structure. They disappear when the context structure dies. Important thing to note here is that context variables from the same scope live in the same structure. Let me illustrate it with an example code:

function outer () {
  var x; // real local variable
  var y; // context variable, referenced by inner1
  var z; // context variable, referenced by inner2

  function inner1 () {
    // references context
    use(y);
  }

  function inner2 () {
    // references context
    use(z);
  }

  function inner3 () { /* I am empty but I still capture context implicitly */ }

  return [inner1, inner2, inner3];
}

在这个例子中,只要 outer 返回,变量 x 就会消失,但变量 yz 会消失仅当 both inner1inner2 inner3 死亡时.发生这种情况是因为 yz 分配在相同的上下文结构中,并且所有三个闭包都隐式引用了这个上下文结构(即使 inner3 不使用它明确).

In this example variable x will disappear as soon as outer returns but variables y and z will disappear only when both inner1, inner2 and inner3 die. This happens because y and z are allocated in the same context structure and all three closures implicitly reference this context structure (even inner3 which does not use it explicitly).

当您开始使用 with-statement、try/catch-statement(在 V8 上包含隐式 with- 语句时,情况变得更加复杂)catch 子句或全局 eval 中的语句.

Situation gets even more complicated when you start using with-statement, try/catch-statement which on V8 contains an implicit with-statement inside catch clause or global eval.

function complication () {
  var x; // context variable

  function inner () { /* I am empty but I still capture context implicitly */ }

  try { } catch (e) { /* contains implicit with-statement */ }

  return inner;
}

在这个例子中 x 只有在 inner 死亡时才会消失.因为:

In this example x will disappear only when inner dies. Because:

  • try/catch-包含隐含的with-catch 子句中的语句
  • V8 假设任何 with-statement 都将 all 本地化
  • try/catch-contains implicit with-statement in catch clause
  • V8 assumes that any with-statement shadows all the locals

这会强制 x 成为上下文变量并且 inner 捕获上下文,因此 x 存在直到 inner 死亡.

This forces x to become a context variable and inner captures the context so x exists until inner dies.

一般来说,如果您想确保给定的变量不会保留某个对象的时间超过实际需要的时间,您可以通过将 null 分配给该变量来轻松销毁此链接.

In general if you want to be sure that given variable does not retain some object for longer than really needed you can easily destroy this link by assigning null to that variable.

这篇关于使用 node.js 进行垃圾收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-19 03:32
查看更多