根据我目前对 VM 及其行为的假设,我认为每次命中闭包的定义时都会分配和编译闭包;与在闭包外声明的函数相比,闭包只分配和编译一次(因为它们被放置在某个地方,它们的定义只被命中一次)。这个假设是否正确?
因此,如果我在 socket.on('data', function (data) {...})
中有一个闭包,V8 会分配新内存(并可能重新编译)闭包 < em>每次套接字收到数据?
最佳答案
I figure closures are allocated and compiled every time their definition is hit
不是真的。闭包编译一次,但每次它们的定义被命中时分配。最重要的是,您必须区分分配和编译。
每个函数的代码(即在源代码中的相同位置)只编译一次,即使该函数在不同环境中被多次实例化也是如此。
在每个实例化上进行编译是没有意义的,就像为每个调用进行编译一样毫无意义(尽管,这实际上是“解释器”所做的,并且边界是流动的,例如对于不在第一个电话)。
如果代码成为优化候选者,或者如果优化失败并且必须取消优化,则代码可能会再次编译(使用更慢但更复杂的编译器);但这不是重点。每个函数在其定义被命中时被分配/实例化,这与局部函数(嵌套在其他函数中)特别相关。
然而,非闭包函数的分配成本为零,因为不需要存储环境指针,也不需要实例对象。
So if I have a closure in
socket.on('data', function (data) {...})
, V8 allocates new memory (and possibly re-compiles) the closure every time data is received by the socket?
不是 function (data) {...}
,它只被实例化一次并传递给 on
调用。
但是,是的,如果您有一个在 ...
部分实例化的闭包,那么每次接收数据和调用处理程序时都会分配一些内存。但无需担心这一点,内存分配既便宜又快速。
如果您正在寻找技术细节,我建议阅读 http://mrale.ph/blog/2012/09/23/grokking-v8-closures-for-fun.html (即使它已经有几年历史了)。
关于javascript - 什么时候在 Node.js V8 中分配和编译闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36529656/