在回调函数中声明的变量是保留在内存中还是在回调执行结束时被销毁?
Do variables declared inside callback functions remain in memory or are they destroyed upon end of callback execution?
我有这段代码;它基本上连接到 mongo 数据库并浏览文档。在每次迭代中,它都会搜索对象的消息数组。它创建消息变量,然后循环遍历它。 回调函数中声明的变量(var msg
)是保留在内存中还是在回调函数执行结束时被销毁?如果var msg
实际上是声明为 let msg
?有没有办法从内存中丢弃整个范围?
MongoClient.connect(mongoUrl, (err, db) => {
assert.equal(null,err);
var collection_data = db.collection('threadContents').find();
collection_data.on('data', (doc) => {
var msg = doc.messages;
for (var variable in msg) {
console.log(msg);
}//forin(msg)
});//collection_data.on
});//mongo.connect
理论上 - 是的。
实际上 - 没那么简单...
在您的示例中,var msg
不会 "leak" 超出其原始范围,因此它很可能会在回调完成其工作时被销毁。
需要注意的一件事 - 这个对象的销毁不必立即发生 - JS 引擎主要是垃圾收集,所以这块内存可以在堆栈上保留一段时间,但它不会再被访问。
如果您在外部作用域中声明此变量,如果该作用域保留在内存中,它可能会保留在内存中(因此,其他代码段可以访问该变量)。您可以在 MDN 的 Closures 部分阅读有关此行为的信息。
另一个需要注意的是console.log
的用法。通常,非原始值(如对象或数组,实际上是 "special" 对象)可以通过引用访问,而不是通过值访问。因此,如果您的 var msg
是非原始的,它很可能会保留在内存中,直到您清除控制台。原始值将被复制,所以严格来说它们仍然会保留在内存中,但可能在内存中的另一个地方(尽管 JIT 引擎可能会尝试优化它并且在没有必要时不复制内存)。
Node.js(以及所有 javascript 引擎)依赖于 tracing garbage collection,这意味着分配的内存以非确定性方式释放,即您无法准确预测它何时会释放发生。这通常不会影响您,但如果您确实希望以可预测的方式释放一些内存块或其他资源,则必须使用一些特殊技术。
在您的具体示例中,'msg' 将被删除,但不要指望它会立即被删除。
我有这段代码;它基本上连接到 mongo 数据库并浏览文档。在每次迭代中,它都会搜索对象的消息数组。它创建消息变量,然后循环遍历它。 回调函数中声明的变量(var msg
)是保留在内存中还是在回调函数执行结束时被销毁?如果var msg
实际上是声明为 let msg
?有没有办法从内存中丢弃整个范围?
MongoClient.connect(mongoUrl, (err, db) => {
assert.equal(null,err);
var collection_data = db.collection('threadContents').find();
collection_data.on('data', (doc) => {
var msg = doc.messages;
for (var variable in msg) {
console.log(msg);
}//forin(msg)
});//collection_data.on
});//mongo.connect
理论上 - 是的。
实际上 - 没那么简单...
在您的示例中,var msg
不会 "leak" 超出其原始范围,因此它很可能会在回调完成其工作时被销毁。
需要注意的一件事 - 这个对象的销毁不必立即发生 - JS 引擎主要是垃圾收集,所以这块内存可以在堆栈上保留一段时间,但它不会再被访问。
如果您在外部作用域中声明此变量,如果该作用域保留在内存中,它可能会保留在内存中(因此,其他代码段可以访问该变量)。您可以在 MDN 的 Closures 部分阅读有关此行为的信息。
另一个需要注意的是console.log
的用法。通常,非原始值(如对象或数组,实际上是 "special" 对象)可以通过引用访问,而不是通过值访问。因此,如果您的 var msg
是非原始的,它很可能会保留在内存中,直到您清除控制台。原始值将被复制,所以严格来说它们仍然会保留在内存中,但可能在内存中的另一个地方(尽管 JIT 引擎可能会尝试优化它并且在没有必要时不复制内存)。
Node.js(以及所有 javascript 引擎)依赖于 tracing garbage collection,这意味着分配的内存以非确定性方式释放,即您无法准确预测它何时会释放发生。这通常不会影响您,但如果您确实希望以可预测的方式释放一些内存块或其他资源,则必须使用一些特殊技术。
在您的具体示例中,'msg' 将被删除,但不要指望它会立即被删除。