admin管理员组文章数量:1287913
function(foo, cb) {
var bigObject = new BigObject();
doFoo(foo, function(e) {
if (e.type === bigObject.type) {
cb();
// bigObject = null;
}
});
}
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.
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 bees an ugly problem.
My question is this: is there any other way to clean those used variables?
EDIT Here's another (real world) example: So I get application from mongodb and pare 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 pareApplications(application, condition, callback) {
var model = database.getModel('Application');
model.find(condition, function (err, applicationFromMongo) {
var result = (applicationFromMongo.applicationID == application.applicationID)
callback(result)
}
}
function(foo, cb) {
var bigObject = new BigObject();
doFoo(foo, function(e) {
if (e.type === bigObject.type) {
cb();
// bigObject = null;
}
});
}
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.
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 bees an ugly problem.
My question is this: is there any other way to clean those used variables?
EDIT Here's another (real world) example: So I get application from mongodb and pare 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 pareApplications(application, condition, callback) {
var model = database.getModel('Application');
model.find(condition, function (err, applicationFromMongo) {
var result = (applicationFromMongo.applicationID == application.applicationID)
callback(result)
}
}
Share
Improve this question
edited Mar 30, 2016 at 10:28
ᴍᴇʜᴏᴠ
5,2764 gold badges45 silver badges60 bronze badges
asked May 8, 2013 at 13:36
Ivan LonginIvan Longin
3,3534 gold badges36 silver badges43 bronze badges
11
-
Let me ask you this - why is this a problem? The
change
handler is meant to be called several times. So how will you (or the GC) ever know when it's really the end of usingbigObject
unless you unbind thechange
event? You seem to want one instance ofbigObject
so that the handler can pare types. You instantiate it once, which reduces the load for every time the handler runs. If you want it to be cleaned up, instantiate it inside the handler every time, or expect it to "leak" memory because that's how it works. – Ian Commented May 8, 2013 at 13:47 - How about using .one() instead of .on()? – frenchie Commented May 8, 2013 at 13:59
- 1 Please notice that I don't use jQuery and I don't bind or register to some event. I just pass callback function to another. I use NODE.JS ! – Ivan Longin Commented May 8, 2013 at 14:25
- 1 What concerne me is that I can potentialy have chain of callbacks...for example business function calls data function which calls mongodb and all munication between these is in callbacks. Maybe callback from mongodb realy clean everything but what with these other callbacks in business and data layers. I suppose that GC only see callback and what is underneath him he doesn't look. I haven't yet run analysis for leaks but I can clearly see that my node.js workers are using too much rss(RAM) memory. – Ivan Longin Commented May 8, 2013 at 15:27
- 1 Yes but in every that kind of callback (in business or data layer) you can have a closure and are you really sure that they will clean up? ... listen to this example. In some other part of code I also have reading from database but in stream. I have stream.on(data){...} event and every time when I collect 1000 records I fire up callback for business layer (in my example in first post it will be this one : callback(result)) ... that implementation of callback function in business layer is actually a closure and it works perfectly fine. Why didn't GC cleaned up that closure after first callback? – Ivan Longin Commented May 8, 2013 at 20:12
2 Answers
Reset to default 2If 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.
That's the best solution - as you noted, the GC doesn't magically know your callback will only be called once.
To build on Brandon's answer: If (for some terrible reason) you are unable to unsubscribe your callback you could always handle deleting the callback yourself:
function createSingleUseCallback(callback)
{
function callbackWrapper()
{
var ret = callback.apply(this, arguments);
delete callback;
return ret;
}
return callbackWrapper;
}
function pareApplications(application, condition, callback)
{
var model = database.getModel('Application');
model.find(condition, createSingleUseCallback(function (err, applicationFromMongo)
{
var result = (applicationFromMongo.applicationID == application.applicationID);
callback(result);
})
}
本文标签: nodejsClosure and callback memory leak in javascriptStack Overflow
版权声明:本文标题:node.js - Closure and callback memory leak in javascript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741329801a2372701.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论