function(foo, cb) {
var bigObject = new BigObject();
doFoo(foo, function(e) {
if (e.type === bigObject.type) {
cb();
// bigObject = null;
}
});
}
以上示例展示了一个典型的、偶然(或者说不是)的内存泄漏闭包。V8垃圾回收器无法确定是否安全地移除bigObject
,因为它在可以被多次调用的回调函数中使用。
一种解决方案是在回调函数的作业完成后将bigObject
设置为null
。但是如果你正在使用许多变量(想象一下有n
个像bigObject
这样的变量,并且它们都在回调中使用),那么清理这些变量会成为一个棘手的问题。
我的问题是:有没有其他方法来清理这些已使用的变量?
编辑 这里还有另一个(现实世界的)例子:所以我从mongodb获取应用并将其与其他应用程序进行比较。 mongodb的回调使用在该回调之外定义的变量application。在我从mongodb获取结果后,我也将其作为回调返回(因为所有都是异步的,我不能只写返回)。所以实际上可能会将回调传播到源头……
function compareApplications(application, condition, callback) {
var model = database.getModel('Application');
model.find(condition, function (err, applicationFromMongo) {
var result = (applicationFromMongo.applicationID == application.applicationID)
callback(result)
}
}
change
处理程序应该被调用多次。那么,除非您取消绑定change
事件,否则您(或GC)如何知道何时真正结束使用bigObject
?您似乎想要一个bigObject
实例,以便处理程序可以比较类型。您只需实例化一次,这样可以减少每次处理程序运行的负载。如果您希望它被清理,请在处理程序内部每次实例化它,或者期望它“泄漏”内存,因为这就是它的工作方式。 - Ianmodel.find
这样的方法应该会在异步操作完成后自动释放对回调函数的引用。这个小代码片段不应该泄漏任何东西(假设model.find
没有错误)。你确定它真的在泄漏吗?你应该进行一些堆分析,看看哪些对象实际上正在泄漏,以及是什么保留了对它们的引用。 - Brandon