javascript中的闭包和回调内存泄漏 [英] Closure and callback memory leak in javascript

查看:95
本文介绍了javascript中的闭包和回调内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

function(foo, cb) {
  var bigObject = new BigObject();
  doFoo(foo, function(e) {
     if (e.type === bigObject.type) {
          cb();
          // bigObject = null;
     }
  });
}



<关闭。 V8垃圾回收器无法确定是否可以安全地删除 bigObject ,因为它被用在可以被调用几次的回调函数中。

The above example shows a classic, accidental (or maybe not) memory-leaking closure. The V8 garbage collector can't determine if it's safe to remove the bigObject because it's being used in the callback function which can be called several times.

一个解决方案是当回调函数中的作业是时,将 bigObject 设置为 null 过度。但是如果你使用很多变量(想象有 n 变量,如 bigObject ,它们都在回调中使用)然后清洗这变成一个丑陋的问题。

One solution is to set bigObject to null when the job in the callback function is over. But if you are using many variables (imagine there is n variables like bigObject, and they are all used in callback) then cleaning this becomes an ugly problem.

我的问题是:有没有其他方法来清理这些使用的变量?

My question is this: is there any other way to clean those used variables?

EDIT 这是另一个(真实世界)示例:所以我从mongodb获取应用程序,并将其与其他应用程序进行比较。从mongodb回调使用的变量应用程序定义的回调。在我从mongodb的结果后,我返回它也作为回调(因为它是所有异步,我不能只写回报)。所以实际上它可能发生,我传播回调一直到源...

EDIT Here's another (real world) example: So I get application from mongodb and compare it to some other application. Callback from mongodb uses variable application that is defined out of that callback. After I get result from mongodb I return it also as a callback (because it is all async and I cant just write return ). So actually it can happen that i propagate callback all the way to the source...

function compareApplications(application, condition, callback) {

    var model = database.getModel('Application');
    model.find(condition, function (err, applicationFromMongo) {
        var result = (applicationFromMongo.applicationID == application.applicationID)
        callback(result)        
    }
}


推荐答案

如果你的回调函数调用一次,然后你应该在调用之后取消订阅,这将释放你的回调+闭包给GC。当你的闭包释放, bigObject 也可以自由收集GC。

If your callback function is only supposed to be called once, then you should unsubscribe after it is called. That will release your callback + closure to the GC. With your closure released, bigObject will also be free to be collected by the GC.

这是最好的解决方案 - 正如你所说,GC并不神奇地知道你的回调只会被调用一次。

That's the best solution - as you noted, the GC doesn't magically know your callback will only be called once.

这篇关于javascript中的闭包和回调内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆